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 |