77 ) |
77 ) |
78 |
78 |
79 | (?P<End> |
79 | (?P<End> |
80 [ \t]* } [ \t]* ;? |
80 [ \t]* } [ \t]* ;? |
81 )""", |
81 )""", |
82 re.VERBOSE | re.DOTALL | re.MULTILINE).search |
82 re.VERBOSE | re.DOTALL | re.MULTILINE, |
|
83 ).search |
83 |
84 |
84 # function to replace comments |
85 # function to replace comments |
85 _commentsub = re.compile(r"""//[^\n]*\n|//[^\n]*$""").sub |
86 _commentsub = re.compile(r"""//[^\n]*\n|//[^\n]*$""").sub |
86 # function to normalize whitespace |
87 # function to normalize whitespace |
87 _normalize = re.compile(r"""[ \t]{2,}""").sub |
88 _normalize = re.compile(r"""[ \t]{2,}""").sub |
88 |
89 |
89 _modules = {} # cache of modules we've seen |
90 _modules = {} # cache of modules we've seen |
90 |
91 |
91 |
92 |
92 class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): |
93 class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): |
93 """ |
94 """ |
94 Mixin class implementing the notion of visibility. |
95 Mixin class implementing the notion of visibility. |
95 """ |
96 """ |
|
97 |
96 def __init__(self): |
98 def __init__(self): |
97 """ |
99 """ |
98 Constructor |
100 Constructor |
99 """ |
101 """ |
100 self.setPublic() |
102 self.setPublic() |
102 |
104 |
103 class Message(ClbrBaseClasses.Module, VisibilityMixin): |
105 class Message(ClbrBaseClasses.Module, VisibilityMixin): |
104 """ |
106 """ |
105 Class to represent a ProtoBuf Message. |
107 Class to represent a ProtoBuf Message. |
106 """ |
108 """ |
|
109 |
107 def __init__(self, module, name, file, lineno): |
110 def __init__(self, module, name, file, lineno): |
108 """ |
111 """ |
109 Constructor |
112 Constructor |
110 |
113 |
111 @param module name of the module containing this message |
114 @param module name of the module containing this message |
112 @type str |
115 @type str |
113 @param name name of this message |
116 @param name name of this message |
114 @type str |
117 @type str |
115 @param file filename containing this message |
118 @param file filename containing this message |
123 |
126 |
124 class Enum(ClbrBaseClasses.Enum, VisibilityMixin): |
127 class Enum(ClbrBaseClasses.Enum, VisibilityMixin): |
125 """ |
128 """ |
126 Class to represent a ProtoBuf Enum. |
129 Class to represent a ProtoBuf Enum. |
127 """ |
130 """ |
|
131 |
128 def __init__(self, module, name, file, lineno): |
132 def __init__(self, module, name, file, lineno): |
129 """ |
133 """ |
130 Constructor |
134 Constructor |
131 |
135 |
132 @param module name of the module containing this enum |
136 @param module name of the module containing this enum |
133 @type str |
137 @type str |
134 @param name name of this enum |
138 @param name name of this enum |
135 @type str |
139 @type str |
136 @param file filename containing this enum |
140 @param file filename containing this enum |
144 |
148 |
145 class Service(ClbrBaseClasses.Class, VisibilityMixin): |
149 class Service(ClbrBaseClasses.Class, VisibilityMixin): |
146 """ |
150 """ |
147 Class to represent a ProtoBuf Service. |
151 Class to represent a ProtoBuf Service. |
148 """ |
152 """ |
|
153 |
149 def __init__(self, module, name, file, lineno): |
154 def __init__(self, module, name, file, lineno): |
150 """ |
155 """ |
151 Constructor |
156 Constructor |
152 |
157 |
153 @param module name of the module containing this service |
158 @param module name of the module containing this service |
154 @type str |
159 @type str |
155 @param name name of this service |
160 @param name name of this service |
156 @type str |
161 @type str |
157 @param file filename containing this service |
162 @param file filename containing this service |
158 @type str |
163 @type str |
159 @param lineno linenumber of the service definition |
164 @param lineno linenumber of the service definition |
160 @type int |
165 @type int |
161 """ |
166 """ |
162 ClbrBaseClasses.Class.__init__(self, module, name, None, file, |
167 ClbrBaseClasses.Class.__init__(self, module, name, None, file, lineno) |
163 lineno) |
|
164 VisibilityMixin.__init__(self) |
168 VisibilityMixin.__init__(self) |
165 |
169 |
166 |
170 |
167 class ServiceMethod(ClbrBaseClasses.Function, VisibilityMixin): |
171 class ServiceMethod(ClbrBaseClasses.Function, VisibilityMixin): |
168 """ |
172 """ |
169 Class to represent a ProtoBuf Service Method. |
173 Class to represent a ProtoBuf Service Method. |
170 """ |
174 """ |
|
175 |
171 def __init__(self, name, file, lineno, signature, returns): |
176 def __init__(self, name, file, lineno, signature, returns): |
172 """ |
177 """ |
173 Constructor |
178 Constructor |
174 |
179 |
175 @param name name of this service method |
180 @param name name of this service method |
176 @type str |
181 @type str |
177 @param file filename containing this service method |
182 @param file filename containing this service method |
178 @type str |
183 @type str |
179 @param lineno linenumber of the service method definition |
184 @param lineno linenumber of the service method definition |
181 @param signature parameter list of the service method |
186 @param signature parameter list of the service method |
182 @type str |
187 @type str |
183 @param returns return type of the service method |
188 @param returns return type of the service method |
184 @type str |
189 @type str |
185 """ |
190 """ |
186 ClbrBaseClasses.Function.__init__(self, None, name, file, lineno, |
191 ClbrBaseClasses.Function.__init__( |
187 signature, |
192 self, |
188 annotation="-> {0}".format(returns)) |
193 None, |
|
194 name, |
|
195 file, |
|
196 lineno, |
|
197 signature, |
|
198 annotation="-> {0}".format(returns), |
|
199 ) |
189 VisibilityMixin.__init__(self) |
200 VisibilityMixin.__init__(self) |
190 |
201 |
191 |
202 |
192 def readmodule_ex(module, path=None): |
203 def readmodule_ex(module, path=None): |
193 """ |
204 """ |
222 src = Utilities.readEncodedFile(file)[0] |
233 src = Utilities.readEncodedFile(file)[0] |
223 except (UnicodeError, OSError): |
234 except (UnicodeError, OSError): |
224 # can't do anything with this module |
235 # can't do anything with this module |
225 _modules[module] = {} |
236 _modules[module] = {} |
226 return {} |
237 return {} |
227 |
238 |
228 _modules[module] = scan(src, file, module) |
239 _modules[module] = scan(src, file, module) |
229 return _modules[module] |
240 return _modules[module] |
230 |
241 |
231 |
242 |
232 def scan(src, file, module): |
243 def scan(src, file, module): |
233 """ |
244 """ |
234 Public method to scan the given source text. |
245 Public method to scan the given source text. |
235 |
246 |
236 @param src source text to be scanned |
247 @param src source text to be scanned |
237 @type str |
248 @type str |
238 @param file file name associated with the source text |
249 @param file file name associated with the source text |
239 @type str |
250 @type str |
240 @param module module name associated with the source text |
251 @param module module name associated with the source text |
241 @type str |
252 @type str |
242 @return dictionary containing the extracted data |
253 @return dictionary containing the extracted data |
243 @rtype dict |
254 @rtype dict |
244 """ |
255 """ |
|
256 |
245 def calculateEndline(lineno, lines): |
257 def calculateEndline(lineno, lines): |
246 """ |
258 """ |
247 Function to calculate the end line. |
259 Function to calculate the end line. |
248 |
260 |
249 @param lineno line number to start at (one based) |
261 @param lineno line number to start at (one based) |
250 @type int |
262 @type int |
251 @param lines list of source lines |
263 @param lines list of source lines |
252 @type list of str |
264 @type list of str |
253 @return end line (one based) |
265 @return end line (one based) |
290 if m.start("Method") >= 0: |
302 if m.start("Method") >= 0: |
291 # found a method definition or function |
303 # found a method definition or function |
292 thisindent = indent |
304 thisindent = indent |
293 meth_name = m.group("MethodName") |
305 meth_name = m.group("MethodName") |
294 meth_sig = m.group("MethodSignature") |
306 meth_sig = m.group("MethodSignature") |
295 meth_sig = meth_sig and meth_sig.replace('\\\n', '') or '' |
307 meth_sig = meth_sig and meth_sig.replace("\\\n", "") or "" |
296 meth_sig = _commentsub('', meth_sig) |
308 meth_sig = _commentsub("", meth_sig) |
297 meth_sig = _normalize(' ', meth_sig) |
309 meth_sig = _normalize(" ", meth_sig) |
298 meth_return = m.group("MethodReturn") |
310 meth_return = m.group("MethodReturn") |
299 meth_return = meth_return and meth_return.replace('\\\n', '') or '' |
311 meth_return = meth_return and meth_return.replace("\\\n", "") or "" |
300 meth_return = _commentsub('', meth_return) |
312 meth_return = _commentsub("", meth_return) |
301 meth_return = _normalize(' ', meth_return) |
313 meth_return = _normalize(" ", meth_return) |
302 lineno += src.count('\n', last_lineno_pos, start) |
314 lineno += src.count("\n", last_lineno_pos, start) |
303 last_lineno_pos = start |
315 last_lineno_pos = start |
304 # close all interfaces/modules indented at least as much |
316 # close all interfaces/modules indented at least as much |
305 while classstack and classstack[-1][1] >= thisindent: |
317 while classstack and classstack[-1][1] >= thisindent: |
306 del classstack[-1] |
318 del classstack[-1] |
307 if classstack: |
319 if classstack: |
308 # it's an interface/module method |
320 # it's an interface/module method |
309 cur_class = classstack[-1][0] |
321 cur_class = classstack[-1][0] |
310 if isinstance(cur_class, Service): |
322 if isinstance(cur_class, Service): |
311 # it's a method |
323 # it's a method |
312 f = ServiceMethod(meth_name, file, lineno, meth_sig, |
324 f = ServiceMethod(meth_name, file, lineno, meth_sig, meth_return) |
313 meth_return) |
|
314 cur_class._addmethod(meth_name, f) |
325 cur_class._addmethod(meth_name, f) |
315 # else it's a nested def |
326 # else it's a nested def |
316 else: |
327 else: |
317 f = None |
328 f = None |
318 else: |
329 else: |
328 |
339 |
329 elif m.start("Message") >= 0: |
340 elif m.start("Message") >= 0: |
330 # we found a message definition |
341 # we found a message definition |
331 thisindent = indent |
342 thisindent = indent |
332 indent += 1 |
343 indent += 1 |
333 lineno += src.count('\n', last_lineno_pos, start) |
344 lineno += src.count("\n", last_lineno_pos, start) |
334 last_lineno_pos = start |
345 last_lineno_pos = start |
335 message_name = m.group("MessageName") |
346 message_name = m.group("MessageName") |
336 # close all messages/services indented at least as much |
347 # close all messages/services indented at least as much |
337 while classstack and classstack[-1][1] >= thisindent: |
348 while classstack and classstack[-1][1] >= thisindent: |
338 del classstack[-1] |
349 del classstack[-1] |
352 thisindent = indent |
363 thisindent = indent |
353 indent += 1 |
364 indent += 1 |
354 # close all messages/services indented at least as much |
365 # close all messages/services indented at least as much |
355 while classstack and classstack[-1][1] >= thisindent: |
366 while classstack and classstack[-1][1] >= thisindent: |
356 del classstack[-1] |
367 del classstack[-1] |
357 lineno += src.count('\n', last_lineno_pos, start) |
368 lineno += src.count("\n", last_lineno_pos, start) |
358 last_lineno_pos = start |
369 last_lineno_pos = start |
359 enum_name = m.group("EnumName") |
370 enum_name = m.group("EnumName") |
360 # remember this Enum |
371 # remember this Enum |
361 cur_class = Enum(module, enum_name, file, lineno) |
372 cur_class = Enum(module, enum_name, file, lineno) |
362 endline = calculateEndline(lineno, srcLines) |
373 endline = calculateEndline(lineno, srcLines) |
373 thisindent = indent |
384 thisindent = indent |
374 indent += 1 |
385 indent += 1 |
375 # close all messages/services indented at least as much |
386 # close all messages/services indented at least as much |
376 while classstack and classstack[-1][1] >= thisindent: |
387 while classstack and classstack[-1][1] >= thisindent: |
377 del classstack[-1] |
388 del classstack[-1] |
378 lineno += src.count('\n', last_lineno_pos, start) |
389 lineno += src.count("\n", last_lineno_pos, start) |
379 last_lineno_pos = start |
390 last_lineno_pos = start |
380 service_name = m.group("ServiceName") |
391 service_name = m.group("ServiceName") |
381 # remember this Service |
392 # remember this Service |
382 cur_class = Service(module, service_name, file, lineno) |
393 cur_class = Service(module, service_name, file, lineno) |
383 endline = calculateEndline(lineno, srcLines) |
394 endline = calculateEndline(lineno, srcLines) |