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

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: address comments 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
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 enum_comment = HeaderParser.single_line_comment_re.match(line)
182 if enum_comment:
183 self._current_comments.append(enum_comment.groups()[0])
175 return 184 return
176 if HeaderParser.multi_line_comment_start_re.match(line): 185 if HeaderParser.multi_line_comment_start_re.match(line):
177 raise Exception('Multi-line comments in enums are not supported in ' + 186 raise Exception('Multi-line comments in enums are not supported in ' +
178 self._path) 187 self._path)
179 enum_end = HeaderParser.enum_end_re.match(line) 188 enum_end = HeaderParser.enum_end_re.match(line)
180 enum_entry = HeaderParser.enum_line_re.match(line) 189 enum_entry = HeaderParser.enum_line_re.match(line)
181 if enum_end: 190 if enum_end:
182 self._ApplyGeneratorDirectives() 191 self._ApplyGeneratorDirectives()
183 self._current_definition.Finalize() 192 self._current_definition.Finalize()
184 self._enum_definitions.append(self._current_definition) 193 self._enum_definitions.append(self._current_definition)
185 self._in_enum = False 194 self._in_enum = False
186 elif enum_entry: 195 elif enum_entry:
187 enum_key = enum_entry.groups()[0] 196 enum_key = enum_entry.groups()[0]
188 enum_value = enum_entry.groups()[2] 197 enum_value = enum_entry.groups()[2]
189 self._current_definition.AppendEntry(enum_key, enum_value) 198 self._current_definition.AppendEntry(enum_key, enum_value)
199 if self._current_comments:
200 self._current_definition.AppendEntryComment(
201 enum_key, ' '.join(self._current_comments))
202 self._current_comments = []
190 203
191 def _ParseMultiLineDirectiveLine(self, line): 204 def _ParseMultiLineDirectiveLine(self, line):
192 multi_line_directive_continuation = ( 205 multi_line_directive_continuation = (
193 HeaderParser.multi_line_directive_continuation_re.match(line)) 206 HeaderParser.multi_line_directive_continuation_re.match(line))
194 multi_line_directive_end = ( 207 multi_line_directive_end = (
195 HeaderParser.multi_line_directive_end_re.match(line)) 208 HeaderParser.multi_line_directive_end_re.match(line))
196 209
197 if multi_line_directive_continuation: 210 if multi_line_directive_continuation:
198 value_cont = multi_line_directive_continuation.groups()[0] 211 value_cont = multi_line_directive_continuation.groups()[0]
199 self._multi_line_generator_directive[1].append(value_cont) 212 self._multi_line_generator_directive[1].append(value_cont)
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 """) 295 """)
283 296
284 enum_template = Template(' public static final int ${NAME} = ${VALUE};') 297 enum_template = Template(' public static final int ${NAME} = ${VALUE};')
285 enum_entries_string = [] 298 enum_entries_string = []
286 enum_names = [] 299 enum_names = []
287 for enum_name, enum_value in enum_definition.entries.iteritems(): 300 for enum_name, enum_value in enum_definition.entries.iteritems():
288 values = { 301 values = {
289 'NAME': enum_name, 302 'NAME': enum_name,
290 'VALUE': enum_value, 303 'VALUE': enum_value,
291 } 304 }
305 enum_comments = enum_definition.comments.get(enum_name)
306 if enum_comments:
307 enum_comments_indent = ' * '
308 comments_line_wrapper = textwrap.TextWrapper(
309 initial_indent=enum_comments_indent,
310 subsequent_indent=enum_comments_indent,
311 width=100)
312 enum_entries_string.append(' /**')
313 enum_entries_string.append(
314 '\n'.join(comments_line_wrapper.wrap(enum_comments)))
315 enum_entries_string.append(' */')
292 enum_entries_string.append(enum_template.substitute(values)) 316 enum_entries_string.append(enum_template.substitute(values))
293 enum_names.append(enum_name) 317 enum_names.append(enum_name)
294 enum_entries_string = '\n'.join(enum_entries_string) 318 enum_entries_string = '\n'.join(enum_entries_string)
295 319
296 enum_names_indent = ' ' * 6 320 enum_names_indent = ' ' * 6
297 wrapper = textwrap.TextWrapper(initial_indent = enum_names_indent, 321 wrapper = textwrap.TextWrapper(initial_indent = enum_names_indent,
298 subsequent_indent = enum_names_indent, 322 subsequent_indent = enum_names_indent,
299 width = 100) 323 width = 100)
300 enum_names_string = '\n'.join(wrapper.wrap(', '.join(enum_names))) 324 enum_names_string = '\n'.join(wrapper.wrap(', '.join(enum_names)))
301 325
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 if options.verbose: 409 if options.verbose:
386 print 'Output paths:' 410 print 'Output paths:'
387 print '\n'.join(output_paths) 411 print '\n'.join(output_paths)
388 412
389 # Used by GYP. 413 # Used by GYP.
390 return ' '.join(output_paths) 414 return ' '.join(output_paths)
391 415
392 416
393 if __name__ == '__main__': 417 if __name__ == '__main__':
394 DoMain(sys.argv[1:]) 418 DoMain(sys.argv[1:])
OLDNEW
« no previous file with comments | « no previous file | build/android/gyp/java_cpp_enum_tests.py » ('j') | build/android/gyp/java_cpp_enum_tests.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698