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

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

Issue 474173002: IDL: Use IdlNullableType wrapper to represent nullable types (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 4 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 """IDL type handling. 4 """IDL type handling.
5 5
6 Classes: 6 Classes:
7 IdlTypeBase 7 IdlTypeBase
8 IdlType 8 IdlType
9 IdlUnionType 9 IdlUnionType
10 IdlArrayOrSequenceType 10 IdlArrayOrSequenceType
11 IdlArrayType 11 IdlArrayType
12 IdlSequenceType 12 IdlSequenceType
13 IdlNullableType
13 """ 14 """
14 15
15 from collections import defaultdict 16 from collections import defaultdict
16 17
17 18
18 ################################################################################ 19 ################################################################################
19 # IDL types 20 # IDL types
20 ################################################################################ 21 ################################################################################
21 22
22 INTEGER_TYPES = frozenset([ 23 INTEGER_TYPES = frozenset([
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 ancestor_name in ancestors[interface_name]) 95 ancestor_name in ancestors[interface_name])
95 96
96 97
97 def set_ancestors(new_ancestors): 98 def set_ancestors(new_ancestors):
98 ancestors.update(new_ancestors) 99 ancestors.update(new_ancestors)
99 100
100 101
101 class IdlTypeBase(object): 102 class IdlTypeBase(object):
102 """Base class for IdlType, IdlUnionType and IdlArrayOrSequenceType.""" 103 """Base class for IdlType, IdlUnionType and IdlArrayOrSequenceType."""
103 104
104 def __init__(self, is_nullable):
105 self.base_type = None
106 self.is_nullable = is_nullable
107
108 def __str__(self): 105 def __str__(self):
109 inner_string = self.inner_string 106 raise NotImplementedError(
110 if self.is_nullable: 107 '__str__() should be defined in subclasses')
111 # FIXME: Dictionary::ConversionContext::setConversionType can't
112 # handle the '?' in nullable types (passes nullability separately).
113 # Update that function to handle nullability from the type name,
114 # simplifying its signature.
115 # return inner_string + '?'
116 return inner_string
117 return inner_string
118 108
119 @property 109 @property
120 def inner_string(self): 110 def is_nullable(self):
121 raise NotImplementedError( 111 return False
122 'inner_string property should be defined in subclasses')
123 112
124 @property 113 @property
125 def is_basic_type(self): 114 def is_basic_type(self):
126 return False 115 return False
127 116
128 @property 117 @property
129 def is_callback_function(self): 118 def is_callback_function(self):
130 return False 119 return False
131 120
132 @property 121 @property
(...skipping 26 matching lines...) Expand all
159 148
160 @property 149 @property
161 def is_string_type(self): 150 def is_string_type(self):
162 return False 151 return False
163 152
164 @property 153 @property
165 def is_union_type(self): 154 def is_union_type(self):
166 return False 155 return False
167 156
168 @property 157 @property
158 def base_type(self):
159 return None
160
161 @property
169 def may_raise_exception_on_conversion(self): 162 def may_raise_exception_on_conversion(self):
170 return False 163 return False
171 164
172 @property 165 @property
173 def name(self): 166 def name(self):
174 if self.is_nullable:
175 return self.inner_name + 'OrNull'
176 return self.inner_name
177
178 @property
179 def inner_name(self):
180 raise NotImplementedError( 167 raise NotImplementedError(
181 'inner_name property should be defined in subclasses') 168 'name property should be defined in subclasses')
182 169
183 def resolve_typedefs(self, typedefs): 170 def resolve_typedefs(self, typedefs):
184 raise NotImplementedError( 171 raise NotImplementedError(
185 'resolve_typedefs should be defined in subclasses') 172 'resolve_typedefs should be defined in subclasses')
186 173
187 174
188 ################################################################################ 175 ################################################################################
189 # IdlType 176 # IdlType
190 ################################################################################ 177 ################################################################################
191 178
192 class IdlType(IdlTypeBase): 179 class IdlType(IdlTypeBase):
193 # FIXME: incorporate Nullable, etc. 180 # FIXME: incorporate Nullable, etc.
194 # to support types like short?[] vs. short[]?, instead of treating these 181 # to support types like short?[] vs. short[]?, instead of treating these
195 # as orthogonal properties (via flags). 182 # as orthogonal properties (via flags).
196 callback_functions = set() 183 callback_functions = set()
197 callback_interfaces = set() 184 callback_interfaces = set()
198 dictionaries = set() 185 dictionaries = set()
199 enums = {} # name -> values 186 enums = {} # name -> values
200 187
201 def __init__(self, base_type, is_nullable=False, is_unrestricted=False): 188 def __init__(self, base_type, is_unrestricted=False):
202 super(IdlType, self).__init__(is_nullable) 189 super(IdlType, self).__init__()
203 if is_unrestricted: 190 if is_unrestricted:
204 self.base_type = 'unrestricted %s' % base_type 191 self.base_type_name = 'unrestricted %s' % base_type
205 else: 192 else:
206 self.base_type = base_type 193 self.base_type_name = base_type
207 194
208 @property 195 def __str__(self):
209 def inner_string(self):
210 return self.base_type 196 return self.base_type
211 197
212 @property 198 @property
213 def is_basic_type(self): 199 def is_basic_type(self):
214 return self.base_type in BASIC_TYPES 200 return self.base_type in BASIC_TYPES
215 201
216 @property 202 @property
217 def is_callback_function(self): 203 def is_callback_function(self):
218 return self.base_type in IdlType.callback_functions 204 return self.base_type in IdlType.callback_functions
219 205
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 return not(self.is_basic_type or 242 return not(self.is_basic_type or
257 self.is_callback_function or 243 self.is_callback_function or
258 self.is_dictionary or 244 self.is_dictionary or
259 self.is_enum or 245 self.is_enum or
260 self.name == 'Any' or 246 self.name == 'Any' or
261 self.name == 'Object' or 247 self.name == 'Object' or
262 self.name == 'Promise') # Promise will be basic in future 248 self.name == 'Promise') # Promise will be basic in future
263 249
264 @property 250 @property
265 def is_string_type(self): 251 def is_string_type(self):
266 return self.inner_name in STRING_TYPES 252 return self.name in STRING_TYPES
267 253
268 @property 254 @property
269 def may_raise_exception_on_conversion(self): 255 def may_raise_exception_on_conversion(self):
270 return (self.is_integer_type or 256 return (self.is_integer_type or
271 self.name in ('ByteString', 'ScalarValueString')) 257 self.name in ('ByteString', 'ScalarValueString'))
272 258
273 @property 259 @property
274 def is_union_type(self): 260 def is_union_type(self):
275 return isinstance(self, IdlUnionType) 261 return isinstance(self, IdlUnionType)
276 262
277 @property 263 @property
278 def inner_name(self): 264 def base_type(self):
279 """Return type name (or inner type name if nullable) 265 return self.base_type_name
266
267 @property
268 def name(self):
269 """Return type name
280 270
281 http://heycam.github.io/webidl/#dfn-type-name 271 http://heycam.github.io/webidl/#dfn-type-name
282 """ 272 """
283 base_type = self.base_type 273 base_type = self.base_type
284 return TYPE_NAMES.get(base_type, base_type) 274 return TYPE_NAMES.get(base_type, base_type)
285 275
286 @classmethod 276 @classmethod
287 def set_callback_functions(cls, new_callback_functions): 277 def set_callback_functions(cls, new_callback_functions):
288 cls.callback_functions.update(new_callback_functions) 278 cls.callback_functions.update(new_callback_functions)
289 279
290 @classmethod 280 @classmethod
291 def set_callback_interfaces(cls, new_callback_interfaces): 281 def set_callback_interfaces(cls, new_callback_interfaces):
292 cls.callback_interfaces.update(new_callback_interfaces) 282 cls.callback_interfaces.update(new_callback_interfaces)
293 283
294 @classmethod 284 @classmethod
295 def set_dictionaries(cls, new_dictionaries): 285 def set_dictionaries(cls, new_dictionaries):
296 cls.dictionaries.update(new_dictionaries) 286 cls.dictionaries.update(new_dictionaries)
297 287
298 @classmethod 288 @classmethod
299 def set_enums(cls, new_enums): 289 def set_enums(cls, new_enums):
300 cls.enums.update(new_enums) 290 cls.enums.update(new_enums)
301 291
302 def resolve_typedefs(self, typedefs): 292 def resolve_typedefs(self, typedefs):
303 # This function either returns |self|, possibly mutated, or leaves this 293 # This function either returns |self| or a different object.
304 # object unmodified and returns a different object. 294 # FIXME: Rename typedefs_resolved().
305 # FIXME: Change to never mutate |self|, and rename typedefs_resolved(). 295 return typedefs.get(self.base_type, self)
306 if self.base_type not in typedefs:
307 return self
308 new_type = typedefs[self.base_type]
309 if type(new_type) != type(self):
310 # If type changes, need to return a different object,
311 # since can't change type(self)
312 return new_type
313 # If type doesn't change, just mutate self to avoid a new object
314 self.__init__(new_type.base_type, self.is_nullable or new_type.is_nullab le)
315 return self
316 296
317 297
318 ################################################################################ 298 ################################################################################
319 # IdlUnionType 299 # IdlUnionType
320 ################################################################################ 300 ################################################################################
321 301
322 class IdlUnionType(IdlTypeBase): 302 class IdlUnionType(IdlTypeBase):
323 # http://heycam.github.io/webidl/#idl-union 303 # http://heycam.github.io/webidl/#idl-union
324 def __init__(self, member_types, is_nullable=False): 304 def __init__(self, member_types):
325 super(IdlUnionType, self).__init__(is_nullable=is_nullable) 305 super(IdlUnionType, self).__init__()
326 self.member_types = member_types 306 self.member_types = member_types
327 307
328 @property 308 @property
329 def is_union_type(self): 309 def is_union_type(self):
330 return True 310 return True
331 311
332 @property 312 @property
333 def inner_name(self): 313 def name(self):
334 """Return type name (or inner type name if nullable) 314 """Return type name (or inner type name if nullable)
335 315
336 http://heycam.github.io/webidl/#dfn-type-name 316 http://heycam.github.io/webidl/#dfn-type-name
337 """ 317 """
338 return 'Or'.join(member_type.name for member_type in self.member_types) 318 return 'Or'.join(member_type.name for member_type in self.member_types)
339 319
340 def resolve_typedefs(self, typedefs): 320 def resolve_typedefs(self, typedefs):
341 self.member_types = [ 321 self.member_types = [
342 typedefs.get(member_type, member_type) 322 typedefs.get(member_type, member_type)
343 for member_type in self.member_types] 323 for member_type in self.member_types]
344 return self 324 return self
345 325
346 326
347 ################################################################################ 327 ################################################################################
348 # IdlArrayOrSequenceType, IdlArrayType, IdlSequenceType 328 # IdlArrayOrSequenceType, IdlArrayType, IdlSequenceType
349 ################################################################################ 329 ################################################################################
350 330
351 class IdlArrayOrSequenceType(IdlTypeBase): 331 class IdlArrayOrSequenceType(IdlTypeBase):
352 """Base class for IdlArrayType and IdlSequenceType.""" 332 """Base class for IdlArrayType and IdlSequenceType."""
353 333
354 def __init__(self, element_type, is_nullable=False): 334 def __init__(self, element_type):
355 super(IdlArrayOrSequenceType, self).__init__(is_nullable) 335 super(IdlArrayOrSequenceType, self).__init__()
356 self.element_type = element_type 336 self.element_type = element_type
357 337
358 def resolve_typedefs(self, typedefs): 338 def resolve_typedefs(self, typedefs):
359 self.element_type = self.element_type.resolve_typedefs(typedefs) 339 self.element_type = self.element_type.resolve_typedefs(typedefs)
360 return self 340 return self
361 341
362 342
363 class IdlArrayType(IdlArrayOrSequenceType): 343 class IdlArrayType(IdlArrayOrSequenceType):
364 def __init__(self, element_type, is_nullable=False): 344 def __init__(self, element_type):
365 super(IdlArrayType, self).__init__(element_type, is_nullable) 345 super(IdlArrayType, self).__init__(element_type)
366 346
367 @property 347 def __str__(self):
368 def inner_string(self):
369 return '%s[]' % self.element_type 348 return '%s[]' % self.element_type
370 349
371 @property 350 @property
372 def inner_name(self): 351 def name(self):
373 return self.element_type.name + 'Array' 352 return self.element_type.name + 'Array'
374 353
375 354
376 class IdlSequenceType(IdlArrayOrSequenceType): 355 class IdlSequenceType(IdlArrayOrSequenceType):
377 def __init__(self, element_type, is_nullable=False): 356 def __init__(self, element_type):
378 super(IdlSequenceType, self).__init__(element_type, is_nullable) 357 super(IdlSequenceType, self).__init__(element_type)
379 358
380 @property 359 def __str__(self):
381 def inner_string(self):
382 return 'sequence<%s>' % self.element_type 360 return 'sequence<%s>' % self.element_type
383 361
384 @property 362 @property
385 def inner_name(self): 363 def name(self):
386 return self.element_type.name + 'Sequence' 364 return self.element_type.name + 'Sequence'
365
366
367 ################################################################################
368 # IdlNullableType
369 ################################################################################
370
371 class IdlNullableType(IdlTypeBase):
372 def __init__(self, inner_type):
373 super(IdlNullableType, self).__init__()
374 self.inner_type = inner_type
375
376 def __str__(self):
377 # FIXME: Dictionary::ConversionContext::setConversionType can't
378 # handle the '?' in nullable types (passes nullability separately).
379 # Update that function to handle nullability from the type name,
380 # simplifying its signature.
381 # return str(self.inner_type) + '?'
382 return str(self.inner_type)
383
384 def __getattr__(self, name):
385 return getattr(self.inner_type, name)
386
387 @property
388 def is_nullable(self):
389 return True
390
391 @property
392 def is_basic_type(self):
393 return self.inner_type.is_basic_type
haraken 2014/08/15 07:43:57 Just a question about Python: Even if we have the
Jens Widell 2014/08/15 08:00:09 Yes, __getattr__ is called as a last resort, if th
haraken 2014/08/15 08:11:07 Makes sense.
394
395 @property
396 def is_callback_function(self):
397 return self.inner_type.is_callback_function
398
399 @property
400 def is_callback_interface(self):
401 return self.inner_type.is_callback_interface
402
403 @property
404 def is_dictionary(self):
405 return self.inner_type.is_dictionary
406
407 @property
408 def is_enum(self):
409 return self.inner_type.is_enum
410
411 @property
412 def is_integer_type(self):
413 return self.inner_type.is_integer_type
414
415 @property
416 def is_numeric_type(self):
417 return self.inner_type.is_numeric_type
418
419 @property
420 def is_primitive_type(self):
421 return self.inner_type.is_primitive_type
422
423 @property
424 def is_interface_type(self):
425 return self.inner_type.is_interface_type
426
427 @property
428 def is_string_type(self):
429 return self.inner_type.is_string_type
430
431 @property
432 def is_union_type(self):
433 return self.inner_type.is_union_type
434
435 @property
436 def base_type(self):
437 return self.inner_type.base_type
438
439 @property
440 def may_raise_exception_on_conversion(self):
441 return self.inner_type.may_raise_exception_on_conversion
442
443 @property
444 def name(self):
445 return self.inner_type.name + 'OrNull'
446
447 def resolve_typedefs(self, typedefs):
448 self.inner_type = self.inner_type.resolve_typedefs(typedefs)
449 return self
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698