| 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 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 Returns True if the dispatch can fall through on failure, False if the code | 436 Returns True if the dispatch can fall through on failure, False if the code |
| 437 always dispatches. | 437 always dispatches. |
| 438 """ | 438 """ |
| 439 | 439 |
| 440 def NullCheck(name): | 440 def NullCheck(name): |
| 441 return '%s === null' % name | 441 return '%s === null' % name |
| 442 | 442 |
| 443 def TypeCheck(name, type): | 443 def TypeCheck(name, type): |
| 444 return '%s is %s' % (name, type) | 444 return '%s is %s' % (name, type) |
| 445 | 445 |
| 446 if position == len(info.arg_infos): | 446 def ShouldGenerateSingleOperation(): |
| 447 if len(overloads) > 1: | 447 if position == len(info.arg_infos): |
| 448 raise Exception('Duplicate operations ' + str(overloads)) | 448 if len(overloads) > 1: |
| 449 operation = overloads[0] | 449 raise Exception('Duplicate operations ' + str(overloads)) |
| 450 self.GenerateSingleOperation(emitter, info, indent, operation) | 450 return True |
| 451 |
| 452 # Check if we dispatch on RequiredCppParameter arguments. In this |
| 453 # case all trailing arguments must be RequiredCppParameter and there |
| 454 # is no need in dispatch. |
| 455 # TODO(antonm): better diagnositics. |
| 456 if position >= len(overloads[0].arguments): |
| 457 def IsRequiredCppParameter(arg): |
| 458 return 'RequiredCppParameter' in arg.ext_attrs |
| 459 last_overload = overloads[-1] |
| 460 if (len(last_overload.arguments) > position and |
| 461 IsRequiredCppParameter(last_overload.arguments[position])): |
| 462 for overload in overloads: |
| 463 args = overload.arguments[position:] |
| 464 if not all([IsRequiredCppParameter(arg) for arg in args]): |
| 465 raise Exception('Invalid overload for RequiredCppParameter') |
| 466 return True |
| 467 |
| 468 return False |
| 469 |
| 470 if ShouldGenerateSingleOperation(): |
| 471 self.GenerateSingleOperation(emitter, info, indent, overloads[-1]) |
| 451 return False | 472 return False |
| 452 | 473 |
| 453 # FIXME: Consider a simpler dispatch that iterates over the | 474 # FIXME: Consider a simpler dispatch that iterates over the |
| 454 # overloads and generates an overload specific check. Revisit | 475 # overloads and generates an overload specific check. Revisit |
| 455 # when we move to named optional arguments. | 476 # when we move to named optional arguments. |
| 456 | 477 |
| 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. | 478 # Partition the overloads to divide and conquer on the dispatch. |
| 477 positive = [] | 479 positive = [] |
| 478 negative = [] | 480 negative = [] |
| 479 first_overload = overloads[0] | 481 first_overload = overloads[0] |
| 480 (param_name, param_type, param_default) = info.arg_infos[position] | 482 (param_name, param_type, param_default) = info.arg_infos[position] |
| 481 | 483 |
| 482 if position < len(first_overload.arguments): | 484 if position < len(first_overload.arguments): |
| 483 # FIXME: This will not work if the second overload has a more | 485 # FIXME: This will not work if the second overload has a more |
| 484 # precise type than the first. E.g., | 486 # precise type than the first. E.g., |
| 485 # void foo(Node x); | 487 # void foo(Node x); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee | 533 # 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. | 534 # that Y = Z-X, so we need to check for Y. |
| 533 true_code = emitter.Emit( | 535 true_code = emitter.Emit( |
| 534 '$(INDENT)if ($COND) {\n' | 536 '$(INDENT)if ($COND) {\n' |
| 535 '$!TRUE' | 537 '$!TRUE' |
| 536 '$(INDENT)}\n', | 538 '$(INDENT)}\n', |
| 537 COND=test, INDENT=indent) | 539 COND=test, INDENT=indent) |
| 538 self.GenerateDispatch( | 540 self.GenerateDispatch( |
| 539 true_code, info, indent + ' ', position + 1, positive) | 541 true_code, info, indent + ' ', position + 1, positive) |
| 540 return True | 542 return True |
| OLD | NEW |