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

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

Issue 2210633002: Modify java_cpp_enum.py to preserve comments (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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 | « no previous file | 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 from datetime import date 8 from datetime import date
9 import re 9 import re
10 import optparse 10 import optparse
11 import os 11 import os
12 from string import Template 12 from string import Template
13 import sys 13 import sys
14 import textwrap 14 import textwrap
15 import zipfile 15 import zipfile
16 16
17 from util import build_utils 17 from util import build_utils
18 18
19 # List of C++ types that are compatible with the Java code generated by this 19 # List of C++ types that are compatible with the Java code generated by this
20 # script. 20 # script.
21 # 21 #
22 # This script can parse .idl files however, at present it ignores special 22 # This script can parse .idl files however, at present it ignores special
23 # rules such as [cpp_enum_prefix_override="ax_attr"]. 23 # rules such as [cpp_enum_prefix_override="ax_attr"].
24 ENUM_FIXED_TYPE_WHITELIST = ['char', 'unsigned char', 24 ENUM_FIXED_TYPE_WHITELIST = ['char', 'unsigned char',
25 'short', 'unsigned short', 25 'short', 'unsigned short',
26 'int', 'int8_t', 'int16_t', 'int32_t', 'uint8_t', 'uint16_t'] 26 'int', 'int8_t', 'int16_t', 'int32_t', 'uint8_t', 'uint16_t']
27 27
28 class EnumDefinition(object): 28 class EnumDefinition(object):
29 def __init__(self, original_enum_name=None, class_name_override=None, 29 def __init__(self, original_enum_name=None, class_name_override=None,
30 enum_package=None, entries=None, fixed_type=None): 30 enum_package=None, entries=None, comments=None, fixed_type=None):
31 self.original_enum_name = original_enum_name 31 self.original_enum_name = original_enum_name
32 self.class_name_override = class_name_override 32 self.class_name_override = class_name_override
33 self.enum_package = enum_package 33 self.enum_package = enum_package
34 self.entries = collections.OrderedDict(entries or []) 34 self.entries = collections.OrderedDict(entries or [])
35 self.comments = collections.OrderedDict(comments or [])
35 self.prefix_to_strip = None 36 self.prefix_to_strip = None
36 self.fixed_type = fixed_type 37 self.fixed_type = fixed_type
37 38
38 def AppendEntry(self, key, value): 39 def AppendEntry(self, key, value):
39 if key in self.entries: 40 if key in self.entries:
40 raise Exception('Multiple definitions of key %s found.' % key) 41 raise Exception('Multiple definitions of key %s found.' % key)
41 self.entries[key] = value 42 self.entries[key] = value
42 43
44 def AppendEntryComment(self, key, value):
45 if key in self.comments:
46 raise Exception('Multiple definitions of key %s found.' % key)
47 self.comments[key] = value
48
43 @property 49 @property
44 def class_name(self): 50 def class_name(self):
45 return self.class_name_override or self.original_enum_name 51 return self.class_name_override or self.original_enum_name
46 52
47 def Finalize(self): 53 def Finalize(self):
48 self._Validate() 54 self._Validate()
49 self._AssignEntryIndices() 55 self._AssignEntryIndices()
50 self._StripPrefix() 56 self._StripPrefix()
51 57
52 def _Validate(self): 58 def _Validate(self):
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 def UpdateDefinition(self, definition): 123 def UpdateDefinition(self, definition):
118 definition.class_name_override = self._directives.get( 124 definition.class_name_override = self._directives.get(
119 DirectiveSet.class_name_override_key, '') 125 DirectiveSet.class_name_override_key, '')
120 definition.enum_package = self._directives.get( 126 definition.enum_package = self._directives.get(
121 DirectiveSet.enum_package_key) 127 DirectiveSet.enum_package_key)
122 definition.prefix_to_strip = self._directives.get( 128 definition.prefix_to_strip = self._directives.get(
123 DirectiveSet.prefix_to_strip_key) 129 DirectiveSet.prefix_to_strip_key)
124 130
125 131
126 class HeaderParser(object): 132 class HeaderParser(object):
127 single_line_comment_re = re.compile(r'\s*//') 133 single_line_comment_re = re.compile(r'\s*//\s*([^\n]+)')
128 multi_line_comment_start_re = re.compile(r'\s*/\*') 134 multi_line_comment_start_re = re.compile(r'\s*/\*')
129 enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?') 135 enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?')
130 enum_end_re = re.compile(r'^\s*}\s*;\.*$') 136 enum_end_re = re.compile(r'^\s*}\s*;\.*$')
131 generator_directive_re = re.compile( 137 generator_directive_re = re.compile(
132 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$') 138 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$')
133 multi_line_generator_directive_start_re = re.compile( 139 multi_line_generator_directive_start_re = re.compile(
134 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*\(([\.\w]*)$') 140 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*\(([\.\w]*)$')
135 multi_line_directive_continuation_re = re.compile( 141 multi_line_directive_continuation_re = re.compile(
136 r'^\s*//\s+([\.\w]+)$') 142 r'^\s*//\s+([\.\w]+)$')
137 multi_line_directive_end_re = re.compile( 143 multi_line_directive_end_re = re.compile(
138 r'^\s*//\s+([\.\w]*)\)$') 144 r'^\s*//\s+([\.\w]*)\)$')
139 145
140 optional_class_or_struct_re = r'(class|struct)?' 146 optional_class_or_struct_re = r'(class|struct)?'
141 enum_name_re = r'(\w+)' 147 enum_name_re = r'(\w+)'
142 optional_fixed_type_re = r'(\:\s*(\w+\s*\w+?))?' 148 optional_fixed_type_re = r'(\:\s*(\w+\s*\w+?))?'
143 enum_start_re = re.compile(r'^\s*(?:\[cpp.*\])?\s*enum\s+' + 149 enum_start_re = re.compile(r'^\s*(?:\[cpp.*\])?\s*enum\s+' +
144 optional_class_or_struct_re + '\s*' + enum_name_re + '\s*' + 150 optional_class_or_struct_re + '\s*' + enum_name_re + '\s*' +
145 optional_fixed_type_re + '\s*{\s*$') 151 optional_fixed_type_re + '\s*{\s*$')
146 152
147 def __init__(self, lines, path=None): 153 def __init__(self, lines, path=None):
148 self._lines = lines 154 self._lines = lines
149 self._path = path 155 self._path = path
150 self._enum_definitions = [] 156 self._enum_definitions = []
151 self._in_enum = False 157 self._in_enum = False
152 self._current_definition = None 158 self._current_definition = None
159 self._current_comments = []
153 self._generator_directives = DirectiveSet() 160 self._generator_directives = DirectiveSet()
154 self._multi_line_generator_directive = None 161 self._multi_line_generator_directive = None
155 162
156 def _ApplyGeneratorDirectives(self): 163 def _ApplyGeneratorDirectives(self):
157 self._generator_directives.UpdateDefinition(self._current_definition) 164 self._generator_directives.UpdateDefinition(self._current_definition)
158 self._generator_directives = DirectiveSet() 165 self._generator_directives = DirectiveSet()
159 166
160 def ParseDefinitions(self): 167 def ParseDefinitions(self):
161 for line in self._lines: 168 for line in self._lines:
162 self._ParseLine(line) 169 self._ParseLine(line)
163 return self._enum_definitions 170 return self._enum_definitions
164 171
165 def _ParseLine(self, line): 172 def _ParseLine(self, line):
166 if self._multi_line_generator_directive: 173 if self._multi_line_generator_directive:
167 self._ParseMultiLineDirectiveLine(line) 174 self._ParseMultiLineDirectiveLine(line)
168 elif not self._in_enum: 175 elif not self._in_enum:
169 self._ParseRegularLine(line) 176 self._ParseRegularLine(line)
170 else: 177 else:
171 self._ParseEnumLine(line) 178 self._ParseEnumLine(line)
172 179
173 def _ParseEnumLine(self, line): 180 def _ParseEnumLine(self, line):
174 if HeaderParser.single_line_comment_re.match(line): 181 if HeaderParser.single_line_comment_re.match(line):
182 enum_comment = HeaderParser.single_line_comment_re.match(line).groups()[0]
agrieve 2016/08/03 23:09:53 nit: Avoid calling match() twice using a variable.
xunjieli 2016/08/04 13:54:22 Done.
183 if len(self._current_comments) > 0:
184 self._current_comments.append(' ')
agrieve 2016/08/03 23:09:53 nit: Could you just use ' '.join() later on rather
xunjieli 2016/08/04 13:54:22 Done. Ah, you are right! I didn't thought about th
185 self._current_comments.append(enum_comment)
175 return 186 return
176 if HeaderParser.multi_line_comment_start_re.match(line): 187 if HeaderParser.multi_line_comment_start_re.match(line):
177 raise Exception('Multi-line comments in enums are not supported in ' + 188 raise Exception('Multi-line comments in enums are not supported in ' +
178 self._path) 189 self._path)
179 enum_end = HeaderParser.enum_end_re.match(line) 190 enum_end = HeaderParser.enum_end_re.match(line)
180 enum_entry = HeaderParser.enum_line_re.match(line) 191 enum_entry = HeaderParser.enum_line_re.match(line)
181 if enum_end: 192 if enum_end:
182 self._ApplyGeneratorDirectives() 193 self._ApplyGeneratorDirectives()
183 self._current_definition.Finalize() 194 self._current_definition.Finalize()
184 self._enum_definitions.append(self._current_definition) 195 self._enum_definitions.append(self._current_definition)
185 self._in_enum = False 196 self._in_enum = False
186 elif enum_entry: 197 elif enum_entry:
187 enum_key = enum_entry.groups()[0] 198 enum_key = enum_entry.groups()[0]
188 enum_value = enum_entry.groups()[2] 199 enum_value = enum_entry.groups()[2]
189 self._current_definition.AppendEntry(enum_key, enum_value) 200 self._current_definition.AppendEntry(enum_key, enum_value)
201 if self._current_comments:
202 self._current_definition.AppendEntryComment(
203 enum_key, ''.join(self._current_comments))
204 self._current_comments = []
190 205
191 def _ParseMultiLineDirectiveLine(self, line): 206 def _ParseMultiLineDirectiveLine(self, line):
192 multi_line_directive_continuation = ( 207 multi_line_directive_continuation = (
193 HeaderParser.multi_line_directive_continuation_re.match(line)) 208 HeaderParser.multi_line_directive_continuation_re.match(line))
194 multi_line_directive_end = ( 209 multi_line_directive_end = (
195 HeaderParser.multi_line_directive_end_re.match(line)) 210 HeaderParser.multi_line_directive_end_re.match(line))
196 211
197 if multi_line_directive_continuation: 212 if multi_line_directive_continuation:
198 value_cont = multi_line_directive_continuation.groups()[0] 213 value_cont = multi_line_directive_continuation.groups()[0]
199 self._multi_line_generator_directive[1].append(value_cont) 214 self._multi_line_generator_directive[1].append(value_cont)
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 """) 297 """)
283 298
284 enum_template = Template(' public static final int ${NAME} = ${VALUE};') 299 enum_template = Template(' public static final int ${NAME} = ${VALUE};')
285 enum_entries_string = [] 300 enum_entries_string = []
286 enum_names = [] 301 enum_names = []
287 for enum_name, enum_value in enum_definition.entries.iteritems(): 302 for enum_name, enum_value in enum_definition.entries.iteritems():
288 values = { 303 values = {
289 'NAME': enum_name, 304 'NAME': enum_name,
290 'VALUE': enum_value, 305 'VALUE': enum_value,
291 } 306 }
307 enum_comments = enum_definition.comments.get(enum_name)
308 if enum_comments:
309 enum_comments_indent = ' * '
310 comments_line_wrapper = textwrap.TextWrapper(
311 initial_indent = enum_comments_indent,
agrieve 2016/08/03 23:09:53 nit: no spaces around = for arguments. initial_in
xunjieli 2016/08/04 13:54:22 Done.
312 subsequent_indent = enum_comments_indent,
313 width = 100)
314 enum_entries_string.append(' /**')
315 enum_entries_string.append(
316 '\n'.join(comments_line_wrapper.wrap(enum_comments)))
317 enum_entries_string.append(' */')
292 enum_entries_string.append(enum_template.substitute(values)) 318 enum_entries_string.append(enum_template.substitute(values))
293 enum_names.append(enum_name) 319 enum_names.append(enum_name)
294 enum_entries_string = '\n'.join(enum_entries_string) 320 enum_entries_string = '\n'.join(enum_entries_string)
295 321
296 enum_names_indent = ' ' * 6 322 enum_names_indent = ' ' * 6
297 wrapper = textwrap.TextWrapper(initial_indent = enum_names_indent, 323 wrapper = textwrap.TextWrapper(initial_indent = enum_names_indent,
298 subsequent_indent = enum_names_indent, 324 subsequent_indent = enum_names_indent,
299 width = 100) 325 width = 100)
300 enum_names_string = '\n'.join(wrapper.wrap(', '.join(enum_names))) 326 enum_names_string = '\n'.join(wrapper.wrap(', '.join(enum_names)))
301 327
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 if options.verbose: 411 if options.verbose:
386 print 'Output paths:' 412 print 'Output paths:'
387 print '\n'.join(output_paths) 413 print '\n'.join(output_paths)
388 414
389 # Used by GYP. 415 # Used by GYP.
390 return ' '.join(output_paths) 416 return ' '.join(output_paths)
391 417
392 418
393 if __name__ == '__main__': 419 if __name__ == '__main__':
394 DoMain(sys.argv[1:]) 420 DoMain(sys.argv[1:])
OLDNEW
« no previous file with comments | « no previous file | build/android/gyp/java_cpp_enum_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698