| OLD | NEW |
| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 def inherits_interface(interface_name, ancestor_name): | 93 def inherits_interface(interface_name, ancestor_name): |
| 93 return (interface_name == ancestor_name or | 94 return (interface_name == ancestor_name or |
| 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, IdlArrayOrSequenceType and IdlNulla
bleType.""" |
| 103 | |
| 104 def __init__(self, is_nullable): | |
| 105 self.base_type = None | |
| 106 self.is_nullable = is_nullable | |
| 107 | 104 |
| 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 def __getattr__(self, name): |
| 120 def inner_string(self): | 110 # Default undefined attributes to None (analogous to Jinja variables). |
| 121 raise NotImplementedError( | 111 # This allows us to not define default properties in the base class, and |
| 122 'inner_string property should be defined in subclasses') | 112 # allows us to relay __getattr__ in IdlNullableType to the inner type. |
| 123 | 113 return None |
| 124 @property | |
| 125 def is_basic_type(self): | |
| 126 return False | |
| 127 | |
| 128 @property | |
| 129 def is_callback_function(self): | |
| 130 return False | |
| 131 | |
| 132 @property | |
| 133 def is_callback_interface(self): | |
| 134 return False | |
| 135 | |
| 136 @property | |
| 137 def is_dictionary(self): | |
| 138 return False | |
| 139 | |
| 140 @property | |
| 141 def is_enum(self): | |
| 142 return False | |
| 143 | |
| 144 @property | |
| 145 def is_integer_type(self): | |
| 146 return False | |
| 147 | |
| 148 @property | |
| 149 def is_numeric_type(self): | |
| 150 return False | |
| 151 | |
| 152 @property | |
| 153 def is_primitive_type(self): | |
| 154 return False | |
| 155 | |
| 156 @property | |
| 157 def is_interface_type(self): | |
| 158 return False | |
| 159 | |
| 160 @property | |
| 161 def is_string_type(self): | |
| 162 return False | |
| 163 | |
| 164 @property | |
| 165 def is_union_type(self): | |
| 166 return False | |
| 167 | |
| 168 @property | |
| 169 def may_raise_exception_on_conversion(self): | |
| 170 return False | |
| 171 | |
| 172 @property | |
| 173 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( | |
| 181 'inner_name property should be defined in subclasses') | |
| 182 | 114 |
| 183 def resolve_typedefs(self, typedefs): | 115 def resolve_typedefs(self, typedefs): |
| 184 raise NotImplementedError( | 116 raise NotImplementedError( |
| 185 'resolve_typedefs should be defined in subclasses') | 117 'resolve_typedefs should be defined in subclasses') |
| 186 | 118 |
| 187 | 119 |
| 188 ################################################################################ | 120 ################################################################################ |
| 189 # IdlType | 121 # IdlType |
| 190 ################################################################################ | 122 ################################################################################ |
| 191 | 123 |
| 192 class IdlType(IdlTypeBase): | 124 class IdlType(IdlTypeBase): |
| 193 # FIXME: incorporate Nullable, etc. | 125 # FIXME: incorporate Nullable, etc. |
| 194 # to support types like short?[] vs. short[]?, instead of treating these | 126 # to support types like short?[] vs. short[]?, instead of treating these |
| 195 # as orthogonal properties (via flags). | 127 # as orthogonal properties (via flags). |
| 196 callback_functions = set() | 128 callback_functions = set() |
| 197 callback_interfaces = set() | 129 callback_interfaces = set() |
| 198 dictionaries = set() | 130 dictionaries = set() |
| 199 enums = {} # name -> values | 131 enums = {} # name -> values |
| 200 | 132 |
| 201 def __init__(self, base_type, is_nullable=False, is_unrestricted=False): | 133 def __init__(self, base_type, is_unrestricted=False): |
| 202 super(IdlType, self).__init__(is_nullable) | 134 super(IdlType, self).__init__() |
| 203 if is_unrestricted: | 135 if is_unrestricted: |
| 204 self.base_type = 'unrestricted %s' % base_type | 136 self.base_type = 'unrestricted %s' % base_type |
| 205 else: | 137 else: |
| 206 self.base_type = base_type | 138 self.base_type = base_type |
| 207 | 139 |
| 208 @property | 140 def __str__(self): |
| 209 def inner_string(self): | |
| 210 return self.base_type | 141 return self.base_type |
| 211 | 142 |
| 212 @property | 143 @property |
| 213 def is_basic_type(self): | 144 def is_basic_type(self): |
| 214 return self.base_type in BASIC_TYPES | 145 return self.base_type in BASIC_TYPES |
| 215 | 146 |
| 216 @property | 147 @property |
| 217 def is_callback_function(self): | 148 def is_callback_function(self): |
| 218 return self.base_type in IdlType.callback_functions | 149 return self.base_type in IdlType.callback_functions |
| 219 | 150 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 return not(self.is_basic_type or | 187 return not(self.is_basic_type or |
| 257 self.is_callback_function or | 188 self.is_callback_function or |
| 258 self.is_dictionary or | 189 self.is_dictionary or |
| 259 self.is_enum or | 190 self.is_enum or |
| 260 self.name == 'Any' or | 191 self.name == 'Any' or |
| 261 self.name == 'Object' or | 192 self.name == 'Object' or |
| 262 self.name == 'Promise') # Promise will be basic in future | 193 self.name == 'Promise') # Promise will be basic in future |
| 263 | 194 |
| 264 @property | 195 @property |
| 265 def is_string_type(self): | 196 def is_string_type(self): |
| 266 return self.inner_name in STRING_TYPES | 197 return self.name in STRING_TYPES |
| 267 | |
| 268 @property | |
| 269 def may_raise_exception_on_conversion(self): | |
| 270 return (self.is_integer_type or | |
| 271 self.name in ('ByteString', 'ScalarValueString')) | |
| 272 | 198 |
| 273 @property | 199 @property |
| 274 def is_union_type(self): | 200 def is_union_type(self): |
| 275 return isinstance(self, IdlUnionType) | 201 return isinstance(self, IdlUnionType) |
| 276 | 202 |
| 277 @property | 203 @property |
| 278 def inner_name(self): | 204 def name(self): |
| 279 """Return type name (or inner type name if nullable) | 205 """Return type name |
| 280 | 206 |
| 281 http://heycam.github.io/webidl/#dfn-type-name | 207 http://heycam.github.io/webidl/#dfn-type-name |
| 282 """ | 208 """ |
| 283 base_type = self.base_type | 209 base_type = self.base_type |
| 284 return TYPE_NAMES.get(base_type, base_type) | 210 return TYPE_NAMES.get(base_type, base_type) |
| 285 | 211 |
| 286 @classmethod | 212 @classmethod |
| 287 def set_callback_functions(cls, new_callback_functions): | 213 def set_callback_functions(cls, new_callback_functions): |
| 288 cls.callback_functions.update(new_callback_functions) | 214 cls.callback_functions.update(new_callback_functions) |
| 289 | 215 |
| 290 @classmethod | 216 @classmethod |
| 291 def set_callback_interfaces(cls, new_callback_interfaces): | 217 def set_callback_interfaces(cls, new_callback_interfaces): |
| 292 cls.callback_interfaces.update(new_callback_interfaces) | 218 cls.callback_interfaces.update(new_callback_interfaces) |
| 293 | 219 |
| 294 @classmethod | 220 @classmethod |
| 295 def set_dictionaries(cls, new_dictionaries): | 221 def set_dictionaries(cls, new_dictionaries): |
| 296 cls.dictionaries.update(new_dictionaries) | 222 cls.dictionaries.update(new_dictionaries) |
| 297 | 223 |
| 298 @classmethod | 224 @classmethod |
| 299 def set_enums(cls, new_enums): | 225 def set_enums(cls, new_enums): |
| 300 cls.enums.update(new_enums) | 226 cls.enums.update(new_enums) |
| 301 | 227 |
| 302 def resolve_typedefs(self, typedefs): | 228 def resolve_typedefs(self, typedefs): |
| 303 # This function either returns |self|, possibly mutated, or leaves this | 229 # This function either returns |self| or a different object. |
| 304 # object unmodified and returns a different object. | 230 # FIXME: Rename typedefs_resolved(). |
| 305 # FIXME: Change to never mutate |self|, and rename typedefs_resolved(). | 231 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 | 232 |
| 317 | 233 |
| 318 ################################################################################ | 234 ################################################################################ |
| 319 # IdlUnionType | 235 # IdlUnionType |
| 320 ################################################################################ | 236 ################################################################################ |
| 321 | 237 |
| 322 class IdlUnionType(IdlTypeBase): | 238 class IdlUnionType(IdlTypeBase): |
| 323 # http://heycam.github.io/webidl/#idl-union | 239 # http://heycam.github.io/webidl/#idl-union |
| 324 def __init__(self, member_types, is_nullable=False): | 240 def __init__(self, member_types): |
| 325 super(IdlUnionType, self).__init__(is_nullable=is_nullable) | 241 super(IdlUnionType, self).__init__() |
| 326 self.member_types = member_types | 242 self.member_types = member_types |
| 327 | 243 |
| 328 @property | 244 @property |
| 329 def is_union_type(self): | 245 def is_union_type(self): |
| 330 return True | 246 return True |
| 331 | 247 |
| 332 @property | 248 @property |
| 333 def inner_name(self): | 249 def name(self): |
| 334 """Return type name (or inner type name if nullable) | 250 """Return type name (or inner type name if nullable) |
| 335 | 251 |
| 336 http://heycam.github.io/webidl/#dfn-type-name | 252 http://heycam.github.io/webidl/#dfn-type-name |
| 337 """ | 253 """ |
| 338 return 'Or'.join(member_type.name for member_type in self.member_types) | 254 return 'Or'.join(member_type.name for member_type in self.member_types) |
| 339 | 255 |
| 340 def resolve_typedefs(self, typedefs): | 256 def resolve_typedefs(self, typedefs): |
| 341 self.member_types = [ | 257 self.member_types = [ |
| 342 typedefs.get(member_type, member_type) | 258 typedefs.get(member_type, member_type) |
| 343 for member_type in self.member_types] | 259 for member_type in self.member_types] |
| 344 return self | 260 return self |
| 345 | 261 |
| 346 | 262 |
| 347 ################################################################################ | 263 ################################################################################ |
| 348 # IdlArrayOrSequenceType, IdlArrayType, IdlSequenceType | 264 # IdlArrayOrSequenceType, IdlArrayType, IdlSequenceType |
| 349 ################################################################################ | 265 ################################################################################ |
| 350 | 266 |
| 351 class IdlArrayOrSequenceType(IdlTypeBase): | 267 class IdlArrayOrSequenceType(IdlTypeBase): |
| 352 """Base class for IdlArrayType and IdlSequenceType.""" | 268 """Base class for IdlArrayType and IdlSequenceType.""" |
| 353 | 269 |
| 354 def __init__(self, element_type, is_nullable=False): | 270 def __init__(self, element_type): |
| 355 super(IdlArrayOrSequenceType, self).__init__(is_nullable) | 271 super(IdlArrayOrSequenceType, self).__init__() |
| 356 self.element_type = element_type | 272 self.element_type = element_type |
| 357 | 273 |
| 358 def resolve_typedefs(self, typedefs): | 274 def resolve_typedefs(self, typedefs): |
| 359 self.element_type = self.element_type.resolve_typedefs(typedefs) | 275 self.element_type = self.element_type.resolve_typedefs(typedefs) |
| 360 return self | 276 return self |
| 361 | 277 |
| 362 | 278 |
| 363 class IdlArrayType(IdlArrayOrSequenceType): | 279 class IdlArrayType(IdlArrayOrSequenceType): |
| 364 def __init__(self, element_type, is_nullable=False): | 280 def __init__(self, element_type): |
| 365 super(IdlArrayType, self).__init__(element_type, is_nullable) | 281 super(IdlArrayType, self).__init__(element_type) |
| 366 | 282 |
| 367 @property | 283 def __str__(self): |
| 368 def inner_string(self): | |
| 369 return '%s[]' % self.element_type | 284 return '%s[]' % self.element_type |
| 370 | 285 |
| 371 @property | 286 @property |
| 372 def inner_name(self): | 287 def name(self): |
| 373 return self.element_type.name + 'Array' | 288 return self.element_type.name + 'Array' |
| 374 | 289 |
| 375 | 290 |
| 376 class IdlSequenceType(IdlArrayOrSequenceType): | 291 class IdlSequenceType(IdlArrayOrSequenceType): |
| 377 def __init__(self, element_type, is_nullable=False): | 292 def __init__(self, element_type): |
| 378 super(IdlSequenceType, self).__init__(element_type, is_nullable) | 293 super(IdlSequenceType, self).__init__(element_type) |
| 379 | 294 |
| 380 @property | 295 def __str__(self): |
| 381 def inner_string(self): | |
| 382 return 'sequence<%s>' % self.element_type | 296 return 'sequence<%s>' % self.element_type |
| 383 | 297 |
| 384 @property | 298 @property |
| 385 def inner_name(self): | 299 def name(self): |
| 386 return self.element_type.name + 'Sequence' | 300 return self.element_type.name + 'Sequence' |
| 301 |
| 302 |
| 303 ################################################################################ |
| 304 # IdlNullableType |
| 305 ################################################################################ |
| 306 |
| 307 class IdlNullableType(IdlTypeBase): |
| 308 def __init__(self, inner_type): |
| 309 super(IdlNullableType, self).__init__() |
| 310 self.inner_type = inner_type |
| 311 |
| 312 def __str__(self): |
| 313 # FIXME: Dictionary::ConversionContext::setConversionType can't |
| 314 # handle the '?' in nullable types (passes nullability separately). |
| 315 # Update that function to handle nullability from the type name, |
| 316 # simplifying its signature. |
| 317 # return str(self.inner_type) + '?' |
| 318 return str(self.inner_type) |
| 319 |
| 320 def __getattr__(self, name): |
| 321 return getattr(self.inner_type, name) |
| 322 |
| 323 @property |
| 324 def is_nullable(self): |
| 325 return True |
| 326 |
| 327 @property |
| 328 def name(self): |
| 329 # DartFix: Don't handle OrNull all classes generated are same regardless |
| 330 # of nullable type. |
| 331 # return self.inner_type.name + 'OrNull' |
| 332 return self.inner_type.name |
| 333 |
| 334 def resolve_typedefs(self, typedefs): |
| 335 self.inner_type = self.inner_type.resolve_typedefs(typedefs) |
| 336 return self |
| OLD | NEW |