OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 """This module provides shared functionality for the systems to generate | 6 """This module provides shared functionality for the systems to generate |
7 wrapping binding from the IDL database.""" | 7 wrapping binding from the IDL database.""" |
8 | 8 |
9 import os | 9 import os |
10 from generator import * | 10 from generator import * |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 if len(overloads) > 1: | 447 if len(overloads) > 1: |
448 raise Exception('Duplicate operations ' + str(overloads)) | 448 raise Exception('Duplicate operations ' + str(overloads)) |
449 operation = overloads[0] | 449 operation = overloads[0] |
450 self.GenerateSingleOperation(emitter, info, indent, operation) | 450 self.GenerateSingleOperation(emitter, info, indent, operation) |
451 return False | 451 return False |
452 | 452 |
453 # FIXME: Consider a simpler dispatch that iterates over the | 453 # FIXME: Consider a simpler dispatch that iterates over the |
454 # overloads and generates an overload specific check. Revisit | 454 # overloads and generates an overload specific check. Revisit |
455 # when we move to named optional arguments. | 455 # when we move to named optional arguments. |
456 | 456 |
457 if position == 0: | |
458 # Optional callback arguments are special. C++ counterparts do not have p roper optional | |
459 # arguments (as in some cases C++ counterparts require ec) and thus 0 ref ptrs are passed | |
460 # instead of missing arguments. That means the only allowed form is a lis t of | |
461 # arguments with trailing optional callbacks and we don't need any dispatc h at all. | |
462 def IsOptionalCallback(arg): return arg.is_optional and 'Callback' in arg. ext_attrs | |
463 first_optional_callback = None | |
464 for (i, arg) in enumerate(overloads[-1].arguments): | |
465 if IsOptionalCallback(arg): | |
466 first_optional_callback = i | |
467 break | |
468 if first_optional_callback is not None: | |
469 for overload in overloads: | |
470 for arg in overload.arguments[first_optional_callback:]: | |
471 if not IsOptionalCallback(arg): | |
472 raise Exception('Invalid overloading with optional callbacks') | |
473 self.GenerateSingleOperation(emitter, info, indent, overloads[-1]) | |
474 return False | |
475 | |
476 # Partition the overloads to divide and conquer on the dispatch. | 457 # Partition the overloads to divide and conquer on the dispatch. |
477 positive = [] | 458 positive = [] |
478 negative = [] | 459 negative = [] |
479 first_overload = overloads[0] | 460 first_overload = overloads[0] |
480 (param_name, param_type, param_default) = info.arg_infos[position] | 461 (param_name, param_type, param_default) = info.arg_infos[position] |
481 | 462 |
482 if position < len(first_overload.arguments): | 463 if position < len(first_overload.arguments): |
483 # FIXME: This will not work if the second overload has a more | 464 # FIXME: This will not work if the second overload has a more |
484 # precise type than the first. E.g., | 465 # precise type than the first. E.g., |
485 # void foo(Node x); | 466 # void foo(Node x); |
486 # void foo(Element x); | 467 # void foo(Element x); |
487 type = DartType(first_overload.arguments[position].type.id) | 468 type = DartType(first_overload.arguments[position].type.id) |
488 test = TypeCheck(param_name, type) | 469 test = TypeCheck(param_name, type) |
489 pred = lambda op: len(op.arguments) > position and DartType(op.arguments[p osition].type.id) == type | 470 pred = lambda op: len(op.arguments) > position and DartType(op.arguments[p osition].type.id) == type |
490 else: | 471 else: |
472 def IsConvertNullToDefaultValue(arg): return 'DartConvertNullToDefaultValu e' in arg.ext_attrs | |
sra1
2012/02/28 22:04:42
Lines too long
antonm
2012/02/29 10:29:40
Done.
| |
473 # Check if we dispatch on ConvertNullToDefaultValue arguments. In this ca se all | |
474 # trailing arguments must be ConvertNullToDefaultValue and there is no nee d in dispatch. | |
475 # TODO(antonm): better diagnositics. | |
476 last_overload = overloads[-1] | |
477 if len(last_overload.arguments) > position and IsConvertNullToDefaultValue (last_overload.arguments[position]): | |
478 for overload in overloads: | |
479 if not all([IsConvertNullToDefaultValue(arg) for arg in overload.argum ents[position:]]): | |
480 raise Exception('Invalid overload with ConvertNullToDefaultValues') | |
481 self.GenerateSingleOperation(emitter, info, indent, last_overload) | |
482 return False | |
podivilov
2012/02/28 17:46:24
Could you please move this to another block, so it
antonm
2012/02/28 19:22:08
Again, I'll do that, but first I'll try to object
sra1
2012/02/28 22:04:42
So it possible (at least theoretically) to have a
antonm
2012/02/29 10:29:40
Yes, IDBDatabase.transaction is exactly the exampl
| |
483 | |
491 type = None | 484 type = None |
492 test = NullCheck(param_name) | 485 test = NullCheck(param_name) |
493 pred = lambda op: position >= len(op.arguments) | 486 pred = lambda op: position >= len(op.arguments) |
494 | 487 |
495 for overload in overloads: | 488 for overload in overloads: |
496 if pred(overload): | 489 if pred(overload): |
497 positive.append(overload) | 490 positive.append(overload) |
498 else: | 491 else: |
499 negative.append(overload) | 492 negative.append(overload) |
500 | 493 |
(...skipping 30 matching lines...) Expand all Loading... | |
531 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee | 524 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee |
532 # that Y = Z-X, so we need to check for Y. | 525 # that Y = Z-X, so we need to check for Y. |
533 true_code = emitter.Emit( | 526 true_code = emitter.Emit( |
534 '$(INDENT)if ($COND) {\n' | 527 '$(INDENT)if ($COND) {\n' |
535 '$!TRUE' | 528 '$!TRUE' |
536 '$(INDENT)}\n', | 529 '$(INDENT)}\n', |
537 COND=test, INDENT=indent) | 530 COND=test, INDENT=indent) |
538 self.GenerateDispatch( | 531 self.GenerateDispatch( |
539 true_code, info, indent + ' ', position + 1, positive) | 532 true_code, info, indent + ' ', position + 1, positive) |
540 return True | 533 return True |
OLD | NEW |