src/eric7/Utilities/ClassBrowsers/protoclbr.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
15 import Utilities 15 import Utilities
16 import Utilities.ClassBrowsers as ClassBrowsers 16 import Utilities.ClassBrowsers as ClassBrowsers
17 from . import ClbrBaseClasses 17 from . import ClbrBaseClasses
18 18
19 SUPPORTED_TYPES = [ClassBrowsers.PROTO_SOURCE] 19 SUPPORTED_TYPES = [ClassBrowsers.PROTO_SOURCE]
20 20
21 _getnext = re.compile( 21 _getnext = re.compile(
22 r""" 22 r"""
23 (?P<String> 23 (?P<String>
24 " [^"\\\n]* (?: \\. [^"\\\n]*)* " 24 " [^"\\\n]* (?: \\. [^"\\\n]*)* "
25 ) 25 )
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 """
200 @type list of str 211 @type list of str
201 @return the resulting dictionary 212 @return the resulting dictionary
202 @rtype dict 213 @rtype dict
203 """ 214 """
204 global _modules 215 global _modules
205 216
206 if module in _modules: 217 if module in _modules:
207 # we've seen this file before... 218 # we've seen this file before...
208 return _modules[module] 219 return _modules[module]
209 220
210 # search the path for the file 221 # search the path for the file
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)
267 # found a matching brace 279 # found a matching brace
268 return lineno + 1 280 return lineno + 1
269 else: 281 else:
270 # nothing found 282 # nothing found
271 return -1 283 return -1
272 284
273 # convert eol markers the Python style 285 # convert eol markers the Python style
274 src = src.replace("\r\n", "\n").replace("\r", "\n") 286 src = src.replace("\r\n", "\n").replace("\r", "\n")
275 srcLines = src.splitlines() 287 srcLines = src.splitlines()
276 288
277 dictionary = {} 289 dictionary = {}
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)

eric ide

mercurial