| OLD | NEW |
| 1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import itertools | 6 import itertools |
| 7 import json | 7 import json |
| 8 import os.path | 8 import os.path |
| 9 import pprint | 9 import pprint |
| 10 import re | 10 import re |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 to other arguments. | 43 to other arguments. |
| 44 |arg2_name|: Description of arg2... | 44 |arg2_name|: Description of arg2... |
| 45 | 45 |
| 46 Newlines are removed, and leading and trailing whitespace is stripped. | 46 Newlines are removed, and leading and trailing whitespace is stripped. |
| 47 | 47 |
| 48 Args: | 48 Args: |
| 49 comment: The string from a Comment node. | 49 comment: The string from a Comment node. |
| 50 | 50 |
| 51 Returns: A tuple that looks like: | 51 Returns: A tuple that looks like: |
| 52 ( | 52 ( |
| 53 "The processed comment, minus all |parameter| mentions and jsexterns.", | 53 "The processed comment, minus all |parameter| mentions.", |
| 54 "Any block wrapped in <jsexterns></jsexterns>.", | |
| 55 { | 54 { |
| 56 'parameter_name_1': "The comment that followed |parameter_name_1|:", | 55 'parameter_name_1': "The comment that followed |parameter_name_1|:", |
| 57 ... | 56 ... |
| 58 } | 57 } |
| 59 ) | 58 ) |
| 60 ''' | 59 ''' |
| 61 jsexterns = None | |
| 62 match = re.search('<jsexterns>(.*)</jsexterns>', comment, re.DOTALL) | |
| 63 if match: | |
| 64 jsexterns = match.group(1).strip() | |
| 65 comment = comment[:match.start()] + comment[match.end():] | |
| 66 | |
| 67 def add_paragraphs(content): | 60 def add_paragraphs(content): |
| 68 paragraphs = content.split('\n\n') | 61 paragraphs = content.split('\n\n') |
| 69 if len(paragraphs) < 2: | 62 if len(paragraphs) < 2: |
| 70 return content | 63 return content |
| 71 return '<p>' + '</p><p>'.join(p.strip() for p in paragraphs) + '</p>' | 64 return '<p>' + '</p><p>'.join(p.strip() for p in paragraphs) + '</p>' |
| 72 | 65 |
| 73 # Find all the parameter comments of the form '|name|: comment'. | 66 # Find all the parameter comments of the form '|name|: comment'. |
| 74 parameter_starts = list(re.finditer(r' *\|([^|]*)\| *: *', comment)) | 67 parameter_starts = list(re.finditer(r' *\|([^|]*)\| *: *', comment)) |
| 75 | 68 |
| 76 # Get the parent comment (everything before the first parameter comment. | 69 # Get the parent comment (everything before the first parameter comment. |
| 77 first_parameter_location = (parameter_starts[0].start() | 70 first_parameter_location = (parameter_starts[0].start() |
| 78 if parameter_starts else len(comment)) | 71 if parameter_starts else len(comment)) |
| 79 parent_comment = (add_paragraphs(comment[:first_parameter_location].strip()) | 72 parent_comment = (add_paragraphs(comment[:first_parameter_location].strip()) |
| 80 .replace('\n', '')) | 73 .replace('\n', '')) |
| 81 | 74 |
| 82 params = OrderedDict() | 75 params = OrderedDict() |
| 83 for (cur_param, next_param) in itertools.izip_longest(parameter_starts, | 76 for (cur_param, next_param) in itertools.izip_longest(parameter_starts, |
| 84 parameter_starts[1:]): | 77 parameter_starts[1:]): |
| 85 param_name = cur_param.group(1) | 78 param_name = cur_param.group(1) |
| 86 | 79 |
| 87 # A parameter's comment goes from the end of its introduction to the | 80 # A parameter's comment goes from the end of its introduction to the |
| 88 # beginning of the next parameter's introduction. | 81 # beginning of the next parameter's introduction. |
| 89 param_comment_start = cur_param.end() | 82 param_comment_start = cur_param.end() |
| 90 param_comment_end = next_param.start() if next_param else len(comment) | 83 param_comment_end = next_param.start() if next_param else len(comment) |
| 91 params[param_name] = ( | 84 params[param_name] = ( |
| 92 add_paragraphs(comment[param_comment_start:param_comment_end].strip()) | 85 add_paragraphs(comment[param_comment_start:param_comment_end].strip()) |
| 93 .replace('\n', '')) | 86 .replace('\n', '')) |
| 94 | 87 |
| 95 return (parent_comment, jsexterns, params) | 88 return (parent_comment, params) |
| 96 | 89 |
| 97 | 90 |
| 98 class Callspec(object): | 91 class Callspec(object): |
| 99 ''' | 92 ''' |
| 100 Given a Callspec node representing an IDL function declaration, converts into | 93 Given a Callspec node representing an IDL function declaration, converts into |
| 101 a tuple: | 94 a tuple: |
| 102 (name, list of function parameters, return type) | 95 (name, list of function parameters, return type) |
| 103 ''' | 96 ''' |
| 104 def __init__(self, callspec_node, comment): | 97 def __init__(self, callspec_node, comment): |
| 105 self.node = callspec_node | 98 self.node = callspec_node |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 ('supportsRules', lambda s: s == 'true')]: | 188 ('supportsRules', lambda s: s == 'true')]: |
| 196 if self.node.GetProperty(option_name): | 189 if self.node.GetProperty(option_name): |
| 197 if 'options' not in properties: | 190 if 'options' not in properties: |
| 198 properties['options'] = {} | 191 properties['options'] = {} |
| 199 properties['options'][option_name] = sanitizer(self.node.GetProperty( | 192 properties['options'][option_name] = sanitizer(self.node.GetProperty( |
| 200 option_name)) | 193 option_name)) |
| 201 type_override = None | 194 type_override = None |
| 202 parameter_comments = OrderedDict() | 195 parameter_comments = OrderedDict() |
| 203 for node in self.node.GetChildren(): | 196 for node in self.node.GetChildren(): |
| 204 if node.cls == 'Comment': | 197 if node.cls == 'Comment': |
| 205 (parent_comment, jsexterns, parameter_comments) = ProcessComment( | 198 (parent_comment, parameter_comments) = ProcessComment(node.GetName()) |
| 206 node.GetName()) | |
| 207 properties['description'] = parent_comment | 199 properties['description'] = parent_comment |
| 208 properties['jsexterns'] = jsexterns | |
| 209 elif node.cls == 'Callspec': | 200 elif node.cls == 'Callspec': |
| 210 name, parameters, return_type = (Callspec(node, parameter_comments) | 201 name, parameters, return_type = (Callspec(node, parameter_comments) |
| 211 .process(callbacks)) | 202 .process(callbacks)) |
| 212 if functions_are_properties: | 203 if functions_are_properties: |
| 213 # If functions are treated as properties (which will happen if the | 204 # If functions are treated as properties (which will happen if the |
| 214 # interface is named Properties) then this isn't a function, it's a | 205 # interface is named Properties) then this isn't a function, it's a |
| 215 # property which is encoded as a function with no arguments. The | 206 # property which is encoded as a function with no arguments. The |
| 216 # property type is the return type. This is an egregious hack in lieu | 207 # property type is the return type. This is an egregious hack in lieu |
| 217 # of the IDL parser supporting 'const'. | 208 # of the IDL parser supporting 'const'. |
| 218 assert parameters == [], ( | 209 assert parameters == [], ( |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 print json.dumps(schema, indent=2) | 551 print json.dumps(schema, indent=2) |
| 561 else: | 552 else: |
| 562 contents = sys.stdin.read() | 553 contents = sys.stdin.read() |
| 563 idl = idl_parser.IDLParser().ParseData(contents, '<stdin>') | 554 idl = idl_parser.IDLParser().ParseData(contents, '<stdin>') |
| 564 schema = IDLSchema(idl).process() | 555 schema = IDLSchema(idl).process() |
| 565 print json.dumps(schema, indent=2) | 556 print json.dumps(schema, indent=2) |
| 566 | 557 |
| 567 | 558 |
| 568 if __name__ == '__main__': | 559 if __name__ == '__main__': |
| 569 Main() | 560 Main() |
| OLD | NEW |