Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(862)

Side by Side Diff: build/android/gyp/java_cpp_enum.py

Issue 670183003: Update from chromium 62675d9fb31fb8cedc40f68e78e8445a74f362e7 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/disable_lto.gypi ('k') | build/android/gyp/java_cpp_enum_tests.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright 2014 The Chromium Authors. All rights reserved. 3 # Copyright 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 import collections 7 import collections
8 import re 8 import re
9 import optparse 9 import optparse
10 import os 10 import os
11 from string import Template 11 from string import Template
12 import sys 12 import sys
13 13
14 from util import build_utils 14 from util import build_utils
15 15
16 class EnumDefinition(object): 16 class EnumDefinition(object):
17 def __init__(self, class_name=None, class_package=None, entries=None): 17 def __init__(self, original_enum_name=None, class_name_override=None,
18 self.class_name = class_name 18 enum_package=None, entries=None):
19 self.class_package = class_package 19 self.original_enum_name = original_enum_name
20 self.class_name_override = class_name_override
21 self.enum_package = enum_package
20 self.entries = collections.OrderedDict(entries or []) 22 self.entries = collections.OrderedDict(entries or [])
21 self.prefix_to_strip = '' 23 self.prefix_to_strip = None
22 24
23 def AppendEntry(self, key, value): 25 def AppendEntry(self, key, value):
24 if key in self.entries: 26 if key in self.entries:
25 raise Exception('Multiple definitions of key %s found.' % key) 27 raise Exception('Multiple definitions of key %s found.' % key)
26 self.entries[key] = value 28 self.entries[key] = value
27 29
30 @property
31 def class_name(self):
32 return self.class_name_override or self.original_enum_name
33
28 def Finalize(self): 34 def Finalize(self):
29 self._Validate() 35 self._Validate()
30 self._AssignEntryIndices() 36 self._AssignEntryIndices()
31 self._StripPrefix() 37 self._StripPrefix()
32 38
33 def _Validate(self): 39 def _Validate(self):
34 assert self.class_name 40 assert self.class_name
35 assert self.class_package 41 assert self.enum_package
36 assert self.entries 42 assert self.entries
37 43
38 def _AssignEntryIndices(self): 44 def _AssignEntryIndices(self):
39 # Enums, if given no value, are given the value of the previous enum + 1. 45 # Enums, if given no value, are given the value of the previous enum + 1.
40 if not all(self.entries.values()): 46 if not all(self.entries.values()):
41 prev_enum_value = -1 47 prev_enum_value = -1
42 for key, value in self.entries.iteritems(): 48 for key, value in self.entries.iteritems():
43 if not value: 49 if not value:
44 self.entries[key] = prev_enum_value + 1 50 self.entries[key] = prev_enum_value + 1
45 elif value in self.entries: 51 elif value in self.entries:
46 self.entries[key] = self.entries[value] 52 self.entries[key] = self.entries[value]
47 else: 53 else:
48 try: 54 try:
49 self.entries[key] = int(value) 55 self.entries[key] = int(value)
50 except ValueError: 56 except ValueError:
51 raise Exception('Could not interpret integer from enum value "%s" ' 57 raise Exception('Could not interpret integer from enum value "%s" '
52 'for key %s.' % (value, key)) 58 'for key %s.' % (value, key))
53 prev_enum_value = self.entries[key] 59 prev_enum_value = self.entries[key]
54 60
55 61
56 def _StripPrefix(self): 62 def _StripPrefix(self):
57 if not self.prefix_to_strip: 63 prefix_to_strip = self.prefix_to_strip
58 prefix_to_strip = re.sub('(?!^)([A-Z]+)', r'_\1', self.class_name).upper() 64 if not prefix_to_strip:
65 prefix_to_strip = self.original_enum_name
66 prefix_to_strip = re.sub('(?!^)([A-Z]+)', r'_\1', prefix_to_strip).upper()
59 prefix_to_strip += '_' 67 prefix_to_strip += '_'
60 if not all([w.startswith(prefix_to_strip) for w in self.entries.keys()]): 68 if not all([w.startswith(prefix_to_strip) for w in self.entries.keys()]):
61 prefix_to_strip = '' 69 prefix_to_strip = ''
62 else: 70
63 prefix_to_strip = self.prefix_to_strip 71 entries = collections.OrderedDict()
64 entries = ((k.replace(prefix_to_strip, '', 1), v) for (k, v) in 72 for (k, v) in self.entries.iteritems():
65 self.entries.iteritems()) 73 stripped_key = k.replace(prefix_to_strip, '', 1)
66 self.entries = collections.OrderedDict(entries) 74 if isinstance(v, basestring):
75 stripped_value = v.replace(prefix_to_strip, '', 1)
76 else:
77 stripped_value = v
78 entries[stripped_key] = stripped_value
79
80 self.entries = entries
81
82 class DirectiveSet(object):
83 class_name_override_key = 'CLASS_NAME_OVERRIDE'
84 enum_package_key = 'ENUM_PACKAGE'
85 prefix_to_strip_key = 'PREFIX_TO_STRIP'
86
87 known_keys = [class_name_override_key, enum_package_key, prefix_to_strip_key]
88
89 def __init__(self):
90 self._directives = {}
91
92 def Update(self, key, value):
93 if key not in DirectiveSet.known_keys:
94 raise Exception("Unknown directive: " + key)
95 self._directives[key] = value
96
97 @property
98 def empty(self):
99 return len(self._directives) == 0
100
101 def UpdateDefinition(self, definition):
102 definition.class_name_override = self._directives.get(
103 DirectiveSet.class_name_override_key, '')
104 definition.enum_package = self._directives.get(
105 DirectiveSet.enum_package_key)
106 definition.prefix_to_strip = self._directives.get(
107 DirectiveSet.prefix_to_strip_key)
108
67 109
68 class HeaderParser(object): 110 class HeaderParser(object):
69 single_line_comment_re = re.compile(r'\s*//') 111 single_line_comment_re = re.compile(r'\s*//')
70 multi_line_comment_start_re = re.compile(r'\s*/\*') 112 multi_line_comment_start_re = re.compile(r'\s*/\*')
71 enum_start_re = re.compile(r'^\s*enum\s+(\w+)\s+{\s*$') 113 enum_start_re = re.compile(r'^\s*enum\s+(\w+)\s+{\s*$')
72 enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?') 114 enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?')
73 enum_end_re = re.compile(r'^\s*}\s*;\s*$') 115 enum_end_re = re.compile(r'^\s*}\s*;\.*$')
74 generator_directive_re = re.compile( 116 generator_directive_re = re.compile(
75 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$') 117 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$')
76 118
77 def __init__(self, lines): 119 def __init__(self, lines):
78 self._lines = lines 120 self._lines = lines
79 self._enum_definitions = [] 121 self._enum_definitions = []
80 self._in_enum = False 122 self._in_enum = False
81 self._current_definition = None 123 self._current_definition = None
82 self._generator_directives = {} 124 self._generator_directives = DirectiveSet()
83 125
84 def ParseDefinitions(self): 126 def ParseDefinitions(self):
85 for line in self._lines: 127 for line in self._lines:
86 self._ParseLine(line) 128 self._ParseLine(line)
87 return self._enum_definitions 129 return self._enum_definitions
88 130
89 def _ParseLine(self, line): 131 def _ParseLine(self, line):
90 if not self._in_enum: 132 if not self._in_enum:
91 self._ParseRegularLine(line) 133 self._ParseRegularLine(line)
92 else: 134 else:
93 self._ParseEnumLine(line) 135 self._ParseEnumLine(line)
94 136
95 def _ParseEnumLine(self, line): 137 def _ParseEnumLine(self, line):
96 if HeaderParser.single_line_comment_re.match(line): 138 if HeaderParser.single_line_comment_re.match(line):
97 return 139 return
98 if HeaderParser.multi_line_comment_start_re.match(line): 140 if HeaderParser.multi_line_comment_start_re.match(line):
99 raise Exception('Multi-line comments in enums are not supported.') 141 raise Exception('Multi-line comments in enums are not supported.')
100 enum_end = HeaderParser.enum_end_re.match(line) 142 enum_end = HeaderParser.enum_end_re.match(line)
101 enum_entry = HeaderParser.enum_line_re.match(line) 143 enum_entry = HeaderParser.enum_line_re.match(line)
102 if enum_end: 144 if enum_end:
103 self._ApplyGeneratorDirectives() 145 self._ApplyGeneratorDirectives()
104 self._current_definition.Finalize() 146 self._current_definition.Finalize()
105 self._enum_definitions.append(self._current_definition) 147 self._enum_definitions.append(self._current_definition)
106 self._in_enum = False 148 self._in_enum = False
107 elif enum_entry: 149 elif enum_entry:
108 enum_key = enum_entry.groups()[0] 150 enum_key = enum_entry.groups()[0]
109 enum_value = enum_entry.groups()[2] 151 enum_value = enum_entry.groups()[2]
110 self._current_definition.AppendEntry(enum_key, enum_value) 152 self._current_definition.AppendEntry(enum_key, enum_value)
111 153
112 def _GetCurrentEnumPackageName(self):
113 return self._generator_directives.get('ENUM_PACKAGE')
114
115 def _GetCurrentEnumPrefixToStrip(self):
116 return self._generator_directives.get('PREFIX_TO_STRIP', '')
117
118 def _ApplyGeneratorDirectives(self): 154 def _ApplyGeneratorDirectives(self):
119 current_definition = self._current_definition 155 self._generator_directives.UpdateDefinition(self._current_definition)
120 current_definition.class_package = self._GetCurrentEnumPackageName() 156 self._generator_directives = DirectiveSet()
121 current_definition.prefix_to_strip = self._GetCurrentEnumPrefixToStrip()
122 self._generator_directives = {}
123 157
124 def _ParseRegularLine(self, line): 158 def _ParseRegularLine(self, line):
125 enum_start = HeaderParser.enum_start_re.match(line) 159 enum_start = HeaderParser.enum_start_re.match(line)
126 generator_directive = HeaderParser.generator_directive_re.match(line) 160 generator_directive = HeaderParser.generator_directive_re.match(line)
127 if enum_start: 161 if enum_start:
128 if not self._GetCurrentEnumPackageName(): 162 if self._generator_directives.empty:
129 return 163 return
130 self._current_definition = EnumDefinition() 164 self._current_definition = EnumDefinition(
131 self._current_definition.class_name = enum_start.groups()[0] 165 original_enum_name=enum_start.groups()[0])
132 self._in_enum = True 166 self._in_enum = True
133 elif generator_directive: 167 elif generator_directive:
134 directive_name = generator_directive.groups()[0] 168 directive_name = generator_directive.groups()[0]
135 directive_value = generator_directive.groups()[1] 169 directive_value = generator_directive.groups()[1]
136 self._generator_directives[directive_name] = directive_value 170 self._generator_directives.Update(directive_name, directive_value)
137 171
138 172
139 def GetScriptName(): 173 def GetScriptName():
140 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) 174 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep)
141 build_index = script_components.index('build') 175 build_index = script_components.index('build')
142 return os.sep.join(script_components[build_index:]) 176 return os.sep.join(script_components[build_index:])
143 177
144 178
145 def DoGenerate(options, source_paths): 179 def DoGenerate(options, source_paths):
146 output_paths = [] 180 output_paths = []
147 for source_path in source_paths: 181 for source_path in source_paths:
148 enum_definitions = DoParseHeaderFile(source_path) 182 enum_definitions = DoParseHeaderFile(source_path)
149 for enum_definition in enum_definitions: 183 for enum_definition in enum_definitions:
150 package_path = enum_definition.class_package.replace('.', os.path.sep) 184 package_path = enum_definition.enum_package.replace('.', os.path.sep)
151 file_name = enum_definition.class_name + '.java' 185 file_name = enum_definition.class_name + '.java'
152 output_path = os.path.join(options.output_dir, package_path, file_name) 186 output_path = os.path.join(options.output_dir, package_path, file_name)
153 output_paths.append(output_path) 187 output_paths.append(output_path)
154 if not options.print_output_only: 188 if not options.print_output_only:
155 build_utils.MakeDirectory(os.path.dirname(output_path)) 189 build_utils.MakeDirectory(os.path.dirname(output_path))
156 DoWriteOutput(source_path, output_path, enum_definition) 190 DoWriteOutput(source_path, output_path, enum_definition)
157 return output_paths 191 return output_paths
158 192
159 193
160 def DoParseHeaderFile(path): 194 def DoParseHeaderFile(path):
(...skipping 25 matching lines...) Expand all
186 values = { 220 values = {
187 'NAME': enum_name, 221 'NAME': enum_name,
188 'VALUE': enum_value, 222 'VALUE': enum_value,
189 } 223 }
190 enum_entries_string.append(enum_template.substitute(values)) 224 enum_entries_string.append(enum_template.substitute(values))
191 enum_entries_string = '\n'.join(enum_entries_string) 225 enum_entries_string = '\n'.join(enum_entries_string)
192 226
193 values = { 227 values = {
194 'CLASS_NAME': enum_definition.class_name, 228 'CLASS_NAME': enum_definition.class_name,
195 'ENUM_ENTRIES': enum_entries_string, 229 'ENUM_ENTRIES': enum_entries_string,
196 'PACKAGE': enum_definition.class_package, 230 'PACKAGE': enum_definition.enum_package,
197 'SCRIPT_NAME': GetScriptName(), 231 'SCRIPT_NAME': GetScriptName(),
198 'SOURCE_PATH': source_path, 232 'SOURCE_PATH': source_path,
199 } 233 }
200 return template.substitute(values) 234 return template.substitute(values)
201 235
202 236
203 def DoWriteOutput(source_path, output_path, enum_definition): 237 def DoWriteOutput(source_path, output_path, enum_definition):
204 with open(output_path, 'w') as out_file: 238 with open(output_path, 'w') as out_file:
205 out_file.write(GenerateOutput(source_path, enum_definition)) 239 out_file.write(GenerateOutput(source_path, enum_definition))
206 240
(...skipping 21 matching lines...) Expand all
228 262
229 output_paths = DoGenerate(options, args) 263 output_paths = DoGenerate(options, args)
230 264
231 if options.assert_files_list: 265 if options.assert_files_list:
232 AssertFilesList(output_paths, options.assert_files_list) 266 AssertFilesList(output_paths, options.assert_files_list)
233 267
234 return " ".join(output_paths) 268 return " ".join(output_paths)
235 269
236 if __name__ == '__main__': 270 if __name__ == '__main__':
237 DoMain(sys.argv[1:]) 271 DoMain(sys.argv[1:])
OLDNEW
« no previous file with comments | « build/android/disable_lto.gypi ('k') | build/android/gyp/java_cpp_enum_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698