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

Side by Side Diff: Source/bindings/scripts/utilities.py

Issue 670663002: IDL: Use IdlReader to compute interface_info_individual (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.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
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Utility functions (file reading, simple IDL parsing by regexes) for IDL build . 5 """Utility functions (file reading, simple IDL parsing by regexes) for IDL build .
6 6
7 Design doc: http://www.chromium.org/developers/design-documents/idl-build 7 Design doc: http://www.chromium.org/developers/design-documents/idl-build
8 """ 8 """
9 9
10 import os 10 import os
11 import cPickle as pickle 11 import cPickle as pickle
12 import re 12 import re
13 import string 13 import string
14 import subprocess 14 import subprocess
15 15
16 16
17 KNOWN_COMPONENTS = frozenset(['core', 'modules']) 17 KNOWN_COMPONENTS = frozenset(['core', 'modules'])
18 18
19 19
20 class IdlBadFilenameError(Exception):
21 """Raised if an IDL filename disagrees with the interface name in the file." ""
22 pass
23
24
25 def idl_filename_to_interface_name(idl_filename): 20 def idl_filename_to_interface_name(idl_filename):
26 # interface name is the root of the basename: InterfaceName.idl 21 # interface name is the root of the basename: InterfaceName.idl
27 return os.path.splitext(os.path.basename(idl_filename))[0] 22 return os.path.splitext(os.path.basename(idl_filename))[0]
28 23
29 24
30 def idl_filename_to_component(idl_filename): 25 def idl_filename_to_component(idl_filename):
31 path = os.path.dirname(os.path.realpath(idl_filename)) 26 path = os.path.dirname(os.path.realpath(idl_filename))
32 while path: 27 while path:
33 dirname, basename = os.path.split(path) 28 dirname, basename = os.path.split(path)
34 if basename.lower() in KNOWN_COMPONENTS: 29 if basename.lower() in KNOWN_COMPONENTS:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 107
113 108
114 ################################################################################ 109 ################################################################################
115 # IDL parsing 110 # IDL parsing
116 # 111 #
117 # We use regular expressions for parsing; this is incorrect (Web IDL is not a 112 # We use regular expressions for parsing; this is incorrect (Web IDL is not a
118 # regular language), but simple and sufficient in practice. 113 # regular language), but simple and sufficient in practice.
119 # Leading and trailing context (e.g. following '{') used to avoid false matches. 114 # Leading and trailing context (e.g. following '{') used to avoid false matches.
120 ################################################################################ 115 ################################################################################
121 116
122 def get_partial_interface_name_from_idl(file_contents):
123 match = re.search(r'partial\s+interface\s+(\w+)\s*{', file_contents)
124 return match and match.group(1)
125
126
127 def get_implements_from_idl(file_contents, interface_name):
128 """Returns lists of implementing and implemented interfaces.
129
130 Rule is: identifier-A implements identifier-B;
131 i.e., implement*ing* implements implement*ed*;
132 http://www.w3.org/TR/WebIDL/#idl-implements-statements
133
134 Returns two lists of interfaces: identifier-As and identifier-Bs.
135 An 'implements' statements can be present in the IDL file for either the
136 implementing or the implemented interface, but not other files.
137 """
138 implements_re = (r'^\s*'
139 r'(\w+)\s+'
140 r'implements\s+'
141 r'(\w+)\s*'
142 r';')
143 implements_matches = re.finditer(implements_re, file_contents, re.MULTILINE)
144 implements_pairs = [match.groups() for match in implements_matches]
145
146 foreign_implements = [pair for pair in implements_pairs
147 if interface_name not in pair]
148 if foreign_implements:
149 left, right = foreign_implements.pop()
150 raise IdlBadFilenameError(
151 'implements statement found in unrelated IDL file.\n'
152 'Statement is:\n'
153 ' %s implements %s;\n'
154 'but filename is unrelated "%s.idl"' %
155 (left, right, interface_name))
156
157 return (
158 [left for left, right in implements_pairs if right == interface_name],
159 [right for left, right in implements_pairs if left == interface_name])
160
161
162 def is_callback_interface_from_idl(file_contents): 117 def is_callback_interface_from_idl(file_contents):
163 match = re.search(r'callback\s+interface\s+\w+\s*{', file_contents) 118 match = re.search(r'callback\s+interface\s+\w+\s*{', file_contents)
164 return bool(match) 119 return bool(match)
165 120
166 121
167 def is_dictionary_from_idl(file_contents):
168 match = re.search(r'dictionary\s+\w+\s*{', file_contents)
169 return bool(match)
170
171
172 def get_parent_interface(file_contents):
173 match = re.search(r'interface\s+'
174 r'\w+\s*'
175 r':\s*(\w+)\s*'
176 r'{',
177 file_contents)
178 return match and match.group(1)
179
180
181 def get_interface_extended_attributes_from_idl(file_contents): 122 def get_interface_extended_attributes_from_idl(file_contents):
182 # Strip comments 123 # Strip comments
183 # re.compile needed b/c Python 2.6 doesn't support flags in re.sub 124 # re.compile needed b/c Python 2.6 doesn't support flags in re.sub
184 single_line_comment_re = re.compile(r'//.*$', flags=re.MULTILINE) 125 single_line_comment_re = re.compile(r'//.*$', flags=re.MULTILINE)
185 block_comment_re = re.compile(r'/\*.*?\*/', flags=re.MULTILINE | re.DOTALL) 126 block_comment_re = re.compile(r'/\*.*?\*/', flags=re.MULTILINE | re.DOTALL)
186 file_contents = re.sub(single_line_comment_re, '', file_contents) 127 file_contents = re.sub(single_line_comment_re, '', file_contents)
187 file_contents = re.sub(block_comment_re, '', file_contents) 128 file_contents = re.sub(block_comment_re, '', file_contents)
188 129
189 match = re.search(r'\[(.*)\]\s*' 130 match = re.search(r'\[(.*)\]\s*'
190 r'((callback|partial)\s+)?' 131 r'((callback|partial)\s+)?'
(...skipping 10 matching lines...) Expand all
201 # FIXME: this splitting is WRONG: it fails on extended attributes where list s of 142 # FIXME: this splitting is WRONG: it fails on extended attributes where list s of
202 # multiple values are used, which are seperated by a comma and a space. 143 # multiple values are used, which are seperated by a comma and a space.
203 parts = [extended_attribute.strip() 144 parts = [extended_attribute.strip()
204 for extended_attribute in re.split(',\s+', extended_attributes_stri ng) 145 for extended_attribute in re.split(',\s+', extended_attributes_stri ng)
205 # Discard empty parts, which may exist due to trailing comma 146 # Discard empty parts, which may exist due to trailing comma
206 if extended_attribute.strip()] 147 if extended_attribute.strip()]
207 for part in parts: 148 for part in parts:
208 name, _, value = map(string.strip, part.partition('=')) 149 name, _, value = map(string.strip, part.partition('='))
209 extended_attributes[name] = value 150 extended_attributes[name] = value
210 return extended_attributes 151 return extended_attributes
211
212
213 def get_put_forward_interfaces_from_idl(file_contents):
214 put_forwards_pattern = (r'\[[^\]]*PutForwards=[^\]]*\]\s+'
215 r'readonly\s+'
216 r'attribute\s+'
217 r'(\w+)')
218 return sorted(set(match.group(1)
219 for match in re.finditer(put_forwards_pattern,
220 file_contents,
221 flags=re.DOTALL)))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698