Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 library kernel.interpreter; | 4 library kernel.interpreter; |
| 5 | 5 |
| 6 import '../ast.dart'; | 6 import '../ast.dart'; |
| 7 import '../ast.dart' as ast show Class; | 7 import '../ast.dart' as ast show Class; |
| 8 | 8 |
| 9 import '../log.dart'; | 9 import '../log.dart'; |
| 10 export '../log.dart'; | 10 export '../log.dart'; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 bindings.add(new Binding(variable, value)); | 79 bindings.add(new Binding(variable, value)); |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 | 82 |
| 83 /// Evaluate expressions. | 83 /// Evaluate expressions. |
| 84 class Evaluator | 84 class Evaluator |
| 85 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> { | 85 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> { |
| 86 Configuration eval(Expression expr, ExpressionConfiguration config) => | 86 Configuration eval(Expression expr, ExpressionConfiguration config) => |
| 87 expr.accept1(this, config); | 87 expr.accept1(this, config); |
| 88 | 88 |
| 89 Configuration evalArgs(List<ArgumentExpression> args, Environment env, | |
| 90 ApplicationContinuation cont) { | |
| 91 if (args.isNotEmpty) { | |
| 92 return new ExpressionConfiguration(args.first.expression, env, | |
| 93 new ActualArgumentsContinuation(args.first, args.skip(1), env, cont)); | |
| 94 } | |
| 95 return new ArgumentContinuationConfiguration(cont, <ArgumentValue>[]); | |
| 96 } | |
| 97 | |
| 89 Configuration defaultExpression( | 98 Configuration defaultExpression( |
| 90 Expression node, ExpressionConfiguration config) { | 99 Expression node, ExpressionConfiguration config) { |
| 91 throw new NotImplemented('Evaluation for expressions of type ' | 100 throw new NotImplemented('Evaluation for expressions of type ' |
| 92 '${node.runtimeType} is not implemented.'); | 101 '${node.runtimeType} is not implemented.'); |
| 93 } | 102 } |
| 94 | 103 |
| 95 Configuration visitInvalidExpression1( | 104 Configuration visitInvalidExpression1( |
| 96 InvalidExpression node, ExpressionConfiguration config) { | 105 InvalidExpression node, ExpressionConfiguration config) { |
| 97 throw 'Invalid expression at ${node.location.toString()}'; | 106 throw 'Invalid expression at ${node.location.toString()}'; |
| 98 } | 107 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 defaultExpression(node, config); | 140 defaultExpression(node, config); |
| 132 | 141 |
| 133 Configuration visitStaticInvocation( | 142 Configuration visitStaticInvocation( |
| 134 StaticInvocation node, ExpressionConfiguration config) { | 143 StaticInvocation node, ExpressionConfiguration config) { |
| 135 if ('print' == node.name.toString()) { | 144 if ('print' == node.name.toString()) { |
| 136 var cont = new PrintContinuation(config.continuation); | 145 var cont = new PrintContinuation(config.continuation); |
| 137 return new ExpressionConfiguration( | 146 return new ExpressionConfiguration( |
| 138 node.arguments.positional.first, config.environment, cont); | 147 node.arguments.positional.first, config.environment, cont); |
| 139 } else { | 148 } else { |
| 140 log.info('static-invocation-${node.target.name.toString()}\n'); | 149 log.info('static-invocation-${node.target.name.toString()}\n'); |
| 141 var cont = new ActualArgumentsContinuation(node.arguments, | 150 |
| 142 node.target.function, config.environment, config.continuation); | 151 List<ArgumentExpression> args = |
| 143 return cont.createCurrentConfiguration(); | 152 _createArgumentExpressionList(node.arguments, node.target.function); |
| 153 ApplicationContinuation cont = new StaticInvocationApplication( | |
| 154 node.target.function, config.continuation); | |
| 155 return new ArgumentsConfiguration(args, config.environment, cont); | |
| 144 } | 156 } |
| 145 } | 157 } |
| 146 | 158 |
| 147 Configuration visitMethodInvocation( | 159 Configuration visitMethodInvocation( |
| 148 MethodInvocation node, ExpressionConfiguration config) { | 160 MethodInvocation node, ExpressionConfiguration config) { |
| 149 // Currently supports only method invocation with <2 arguments and is used | 161 // Currently supports only method invocation with <2 arguments and is used |
| 150 // to evaluate implemented operators for int, double and String values. | 162 // to evaluate implemented operators for int, double and String values. |
| 151 var cont = new MethodInvocationContinuation( | 163 var cont = new MethodInvocationContinuation( |
| 152 node.arguments, node.name, config.environment, config.continuation); | 164 node.arguments, node.name, config.environment, config.continuation); |
| 153 | 165 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 } | 333 } |
| 322 } | 334 } |
| 323 | 335 |
| 324 /// Represents the configuration for applying an [ExpressionContinuation]. | 336 /// Represents the configuration for applying an [ExpressionContinuation]. |
| 325 class ContinuationConfiguration extends Configuration { | 337 class ContinuationConfiguration extends Configuration { |
| 326 final ExpressionContinuation continuation; | 338 final ExpressionContinuation continuation; |
| 327 final Value value; | 339 final Value value; |
| 328 | 340 |
| 329 ContinuationConfiguration(this.continuation, this.value); | 341 ContinuationConfiguration(this.continuation, this.value); |
| 330 | 342 |
| 331 Configuration step(StatementExecuter executer) => continuation(value); | 343 Configuration step(StatementExecuter _) => continuation(value); |
| 344 } | |
| 345 | |
| 346 /// Represents the configuration for applying an [ApplicationContinuation]. | |
| 347 class ArgumentContinuationConfiguration extends Configuration { | |
| 348 final ApplicationContinuation continuation; | |
| 349 final List<ArgumentValue> argumentValues; | |
| 350 | |
| 351 ArgumentContinuationConfiguration(this.continuation, this.argumentValues); | |
| 352 | |
| 353 Configuration step(StatementExecuter _) => continuation(argumentValues); | |
| 332 } | 354 } |
| 333 | 355 |
| 334 /// Represents the configuration for evaluating an [Expression]. | 356 /// Represents the configuration for evaluating an [Expression]. |
| 335 class ExpressionConfiguration extends Configuration { | 357 class ExpressionConfiguration extends Configuration { |
| 336 final Expression expression; | 358 final Expression expression; |
| 337 | 359 |
| 338 /// Environment in which the expression is evaluated. | 360 /// Environment in which the expression is evaluated. |
| 339 final Environment environment; | 361 final Environment environment; |
| 340 | 362 |
| 341 /// Next continuation to be applied. | 363 /// Next continuation to be applied. |
| 342 final ExpressionContinuation continuation; | 364 final Continuation continuation; |
| 343 | 365 |
| 344 ExpressionConfiguration(this.expression, this.environment, this.continuation); | 366 ExpressionConfiguration(this.expression, this.environment, this.continuation); |
| 345 | 367 |
| 346 Configuration step(StatementExecuter executer) => | 368 Configuration step(StatementExecuter executer) => |
| 347 executer.eval(expression, this); | 369 executer.eval(expression, this); |
| 348 } | 370 } |
| 349 | 371 |
| 372 /// Represents the configuration for evaluating a list of argument expressions. | |
| 373 class ArgumentsConfiguration extends Configuration { | |
| 374 final List<ArgumentExpression> arguments; | |
| 375 final Environment environment; | |
| 376 final Continuation continuation; | |
| 377 | |
| 378 ArgumentsConfiguration(this.arguments, this.environment, this.continuation); | |
| 379 | |
| 380 Configuration step(StatementExecuter executer) => | |
| 381 executer.evalArgs(arguments, environment, continuation); | |
| 382 } | |
| 383 | |
| 384 abstract class ArgumentExpression { | |
| 385 Expression get expression; | |
| 386 } | |
| 387 | |
| 388 class PositionalArgumentExpression extends ArgumentExpression { | |
| 389 final Expression expression; | |
| 390 | |
| 391 PositionalArgumentExpression(this.expression); | |
| 392 } | |
| 393 | |
| 394 class NamedArgumentExpression extends ArgumentExpression { | |
| 395 final String name; | |
| 396 final Expression expression; | |
| 397 | |
| 398 NamedArgumentExpression(this.name, this.expression); | |
| 399 } | |
| 400 | |
| 401 abstract class ArgumentValue { | |
| 402 Value get value; | |
| 403 } | |
| 404 | |
| 405 class PositionalArgumentValue extends ArgumentValue { | |
| 406 final Value value; | |
| 407 | |
| 408 PositionalArgumentValue(this.value); | |
| 409 } | |
| 410 | |
| 411 class NamedArgumentValue extends ArgumentValue { | |
| 412 final String name; | |
| 413 final Value value; | |
| 414 | |
| 415 NamedArgumentValue(this.name, this.value); | |
| 416 } | |
| 417 | |
| 418 abstract class Continuation {} | |
| 419 | |
| 420 /// Represents the continuation called after the evaluation of argument | |
| 421 /// expressions. | |
| 422 abstract class ApplicationContinuation extends Continuation { | |
| 423 Configuration call(List<ArgumentValue> args); | |
| 424 | |
| 425 /// Creates an environment binding actual argument values to formal parameters | |
| 426 /// of the function in a new environment, which is used to execute the | |
| 427 /// body od the function. | |
| 428 static Environment createEnvironment( | |
| 429 FunctionNode function, List<ArgumentValue> args) { | |
| 430 Environment newEnv = new Environment.empty(); | |
| 431 List<PositionalArgumentValue> positional = args.reversed | |
| 432 .where((ArgumentValue av) => av is PositionalArgumentValue) | |
| 433 .toList(); | |
| 434 | |
| 435 // Add positional parameters. | |
| 436 for (int i = 0; i < positional.length; ++i) { | |
| 437 newEnv.expand(function.positionalParameters[i], positional[i].value); | |
| 438 } | |
| 439 | |
| 440 Map<String, Value> named = new Map.fromIterable( | |
| 441 args.where((ArgumentValue av) => av is NamedArgumentValue), | |
| 442 key: (NamedArgumentValue av) => av.name, | |
| 443 value: (NamedArgumentValue av) => av.value); | |
| 444 | |
| 445 // Add named parameters. | |
| 446 for (VariableDeclaration v in function.namedParameters) { | |
| 447 newEnv.expand(v, named[v.name.toString()]); | |
| 448 } | |
| 449 | |
| 450 return newEnv; | |
| 451 } | |
| 452 } | |
| 453 | |
| 454 /// Represents the application continuation for static invocation. | |
| 455 class StaticInvocationApplication extends ApplicationContinuation { | |
| 456 final FunctionNode function; | |
| 457 final ExpressionContinuation continuation; | |
| 458 | |
| 459 StaticInvocationApplication(this.function, this.continuation); | |
| 460 | |
| 461 Configuration call(List<ArgumentValue> args) { | |
| 462 Environment functionEnv = | |
| 463 ApplicationContinuation.createEnvironment(function, args); | |
| 464 | |
| 465 State bodyState = new State.initial() | |
| 466 .withExpressionContinuation(continuation) | |
| 467 .withConfiguration(new ExitConfiguration(continuation)) | |
| 468 .withEnvironment(functionEnv); | |
| 469 return new StatementConfiguration(function.body, bodyState); | |
| 470 } | |
| 471 } | |
| 472 | |
| 473 /// Represents the application continuation called after the evaluation of all | |
| 474 /// argument expressions for an invocation. | |
| 475 class ArgumentValueApplication extends ApplicationContinuation { | |
| 476 final ArgumentValue value; | |
| 477 final ApplicationContinuation applicationContinuation; | |
| 478 | |
| 479 ArgumentValueApplication(this.value, this.applicationContinuation); | |
| 480 | |
| 481 Configuration call(List<ArgumentValue> args) { | |
| 482 args.add(value); | |
| 483 return new ArgumentContinuationConfiguration(applicationContinuation, args); | |
| 484 } | |
| 485 } | |
| 486 | |
| 350 /// Represents an expression continuation. | 487 /// Represents an expression continuation. |
| 351 abstract class ExpressionContinuation { | 488 abstract class ExpressionContinuation extends Continuation { |
| 352 Configuration call(Value v); | 489 Configuration call(Value v); |
| 353 } | 490 } |
| 354 | 491 |
| 355 /// Represents a continuation that returns the next [StatementConfiguration] | 492 /// Represents a continuation that returns the next [StatementConfiguration] |
| 356 /// to be executed. | 493 /// to be executed. |
| 357 class ExpressionStatementContinuation extends ExpressionContinuation { | 494 class ExpressionStatementContinuation extends ExpressionContinuation { |
| 358 final StatementConfiguration configuration; | 495 final StatementConfiguration configuration; |
| 359 | 496 |
| 360 ExpressionStatementContinuation(this.configuration); | 497 ExpressionStatementContinuation(this.configuration); |
| 361 | 498 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 Setter setter = receiver.class_.lookupSetter(name); | 552 Setter setter = receiver.class_.lookupSetter(name); |
| 416 setter(receiver, v); | 553 setter(receiver, v); |
| 417 return new ContinuationConfiguration(continuation, v); | 554 return new ContinuationConfiguration(continuation, v); |
| 418 } | 555 } |
| 419 } | 556 } |
| 420 | 557 |
| 421 /// Represents a continuation to be called after the evaluation of an actual | 558 /// Represents a continuation to be called after the evaluation of an actual |
| 422 /// argument for function invocation. | 559 /// argument for function invocation. |
| 423 /// TODO: Add checks for validation of arguments according to spec. | 560 /// TODO: Add checks for validation of arguments according to spec. |
| 424 class ActualArgumentsContinuation extends ExpressionContinuation { | 561 class ActualArgumentsContinuation extends ExpressionContinuation { |
| 425 final Arguments arguments; | 562 final ArgumentExpression currentArgument; |
| 426 final FunctionNode functionNode; | 563 final List<ArgumentExpression> arguments; |
| 427 final Environment environment; | 564 final Environment environment; |
| 428 final ExpressionContinuation continuation; | 565 final ApplicationContinuation applicationContinuation; |
| 429 | 566 |
| 430 final List<Value> _positional = <Value>[]; | 567 ActualArgumentsContinuation(this.currentArgument, this.arguments, |
| 431 int _currentPositional = 0; | 568 this.environment, this.applicationContinuation); |
| 432 final Map<String, Value> _named = <String, Value>{}; | |
| 433 int _currentNamed = 0; | |
| 434 | |
| 435 ActualArgumentsContinuation( | |
| 436 this.arguments, this.functionNode, this.environment, this.continuation); | |
| 437 | 569 |
| 438 Configuration call(Value v) { | 570 Configuration call(Value v) { |
| 439 if (_currentPositional < arguments.positional.length) { | 571 ArgumentValue argumentValue; |
| 440 _positional.add(v); | 572 if (currentArgument is NamedArgumentExpression) { |
| 441 _currentPositional++; | 573 argumentValue = new NamedArgumentValue( |
| 574 (currentArgument as NamedArgumentExpression).name, v); | |
|
Dmitry Stefantsov
2017/05/10 08:41:45
Btw, we don't need the "as" cast here, because of
zhivkag
2017/05/10 09:11:07
Type promotion doesn't seem to be working in this
| |
| 442 } else { | 575 } else { |
| 443 assert(_currentNamed < arguments.named.length); | 576 assert(currentArgument is PositionalArgumentExpression); |
| 444 String name = arguments.named[_currentNamed].name; | 577 argumentValue = new PositionalArgumentValue(v); |
| 445 _named[name] = v; | |
| 446 _currentNamed++; | |
| 447 } | 578 } |
| 448 | 579 |
| 449 return createCurrentConfiguration(); | 580 return new ArgumentsConfiguration(arguments, environment, |
| 450 } | 581 new ArgumentValueApplication(argumentValue, applicationContinuation)); |
| 451 | |
| 452 Configuration createCurrentConfiguration() { | |
| 453 // Next argument to evaluate is a provided positional argument. | |
| 454 if (_currentPositional < arguments.positional.length) { | |
| 455 return new ExpressionConfiguration( | |
| 456 arguments.positional[_currentPositional], environment, this); | |
| 457 } | |
| 458 // Next argument to evaluate is a provided named argument. | |
| 459 if (_currentNamed < arguments.named.length) { | |
| 460 return new ExpressionConfiguration( | |
| 461 arguments.named[_currentNamed].value, environment, this); | |
| 462 } | |
| 463 | |
| 464 // TODO: check if the number of actual arguments is larger then the number | |
| 465 // of required arguments and smaller then the number of formal arguments. | |
| 466 | |
| 467 return new OptionalArgumentsContinuation( | |
| 468 _positional, _named, functionNode, environment, continuation) | |
| 469 .createCurrentConfiguration(); | |
| 470 } | 582 } |
| 471 } | 583 } |
| 472 | 584 |
| 473 class OptionalArgumentsContinuation extends ExpressionContinuation { | |
| 474 final List<Value> positional; | |
| 475 final Map<String, Value> named; | |
| 476 final FunctionNode functionNode; | |
| 477 final Environment environment; | |
| 478 final ExpressionContinuation continuation; | |
| 479 | |
| 480 final Map<String, VariableDeclaration> _missingFormalNamed = | |
| 481 <String, VariableDeclaration>{}; | |
| 482 | |
| 483 int _currentPositional; | |
| 484 String _currentNamed; | |
| 485 | |
| 486 OptionalArgumentsContinuation(this.positional, this.named, this.functionNode, | |
| 487 this.environment, this.continuation) { | |
| 488 _currentPositional = positional.length; | |
| 489 assert(_currentPositional >= functionNode.requiredParameterCount); | |
| 490 | |
| 491 for (VariableDeclaration vd in functionNode.namedParameters) { | |
| 492 if (named[vd.name] == null) { | |
| 493 _missingFormalNamed[vd.name] = vd; | |
| 494 } | |
| 495 } | |
| 496 } | |
| 497 | |
| 498 Configuration call(Value v) { | |
| 499 if (_currentPositional < functionNode.positionalParameters.length) { | |
| 500 // Value is a optional positional argument | |
| 501 positional.add(v); | |
| 502 _currentPositional++; | |
| 503 } else { | |
| 504 // Value is a optional named argument. | |
| 505 assert(named[_currentNamed] == null); | |
| 506 named[_currentNamed] = v; | |
| 507 } | |
| 508 | |
| 509 return createCurrentConfiguration(); | |
| 510 } | |
| 511 | |
| 512 /// Creates the current configuration for the evaluation of invocation a | |
| 513 /// function. | |
| 514 Configuration createCurrentConfiguration() { | |
| 515 if (_currentPositional < functionNode.positionalParameters.length) { | |
| 516 // Next argument to evaluate is a missing positional argument. | |
| 517 // Evaluate its initializer. | |
| 518 return new ExpressionConfiguration( | |
| 519 functionNode.positionalParameters[_currentPositional].initializer, | |
| 520 environment, | |
| 521 this); | |
| 522 } | |
| 523 if (named.length < functionNode.namedParameters.length) { | |
| 524 // Next argument to evaluate is a missing named argument. | |
| 525 // Evaluate its initializer. | |
| 526 _currentNamed = _missingFormalNamed.keys.first; | |
| 527 Expression initializer = _missingFormalNamed[_currentNamed].initializer; | |
| 528 _missingFormalNamed.remove(_currentNamed); | |
| 529 return new ExpressionConfiguration(initializer, environment, this); | |
| 530 } | |
| 531 | |
| 532 Environment newEnv = _createEnvironment(); | |
| 533 State bodyState = new State.initial() | |
| 534 .withExpressionContinuation(continuation) | |
| 535 .withConfiguration(new ExitConfiguration(continuation)) | |
| 536 .withEnvironment(newEnv); | |
| 537 | |
| 538 return new StatementConfiguration(functionNode.body, bodyState); | |
| 539 } | |
| 540 | |
| 541 /// Creates an environment binding actual argument values to formal parameters | |
| 542 /// of the function in a new environment, which is used to execute the | |
| 543 /// body od the function. | |
| 544 Environment _createEnvironment() { | |
| 545 Environment newEnv = new Environment.empty(); | |
| 546 // Add positional parameters. | |
| 547 for (int i = 0; i < positional.length; ++i) { | |
| 548 newEnv.expand(functionNode.positionalParameters[i], positional[i]); | |
| 549 } | |
| 550 // Add named parameters. | |
| 551 for (VariableDeclaration v in functionNode.namedParameters) { | |
| 552 newEnv.expand(v, named[v.name.toString()]); | |
| 553 } | |
| 554 | |
| 555 return newEnv; | |
| 556 } | |
| 557 } | |
| 558 | |
| 559 class MethodInvocationContinuation extends ExpressionContinuation { | 585 class MethodInvocationContinuation extends ExpressionContinuation { |
| 560 final Arguments arguments; | 586 final Arguments arguments; |
| 561 final Name methodName; | 587 final Name methodName; |
| 562 final Environment environment; | 588 final Environment environment; |
| 563 final ExpressionContinuation continuation; | 589 final ExpressionContinuation continuation; |
| 564 | 590 |
| 565 MethodInvocationContinuation( | 591 MethodInvocationContinuation( |
| 566 this.arguments, this.methodName, this.environment, this.continuation); | 592 this.arguments, this.methodName, this.environment, this.continuation); |
| 567 | 593 |
| 568 Configuration call(Value receiver) { | 594 Configuration call(Value receiver) { |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 void trampolinedExecution(Configuration configuration) { | 807 void trampolinedExecution(Configuration configuration) { |
| 782 while (configuration != null) { | 808 while (configuration != null) { |
| 783 configuration = configuration.step(this); | 809 configuration = configuration.step(this); |
| 784 } | 810 } |
| 785 } | 811 } |
| 786 | 812 |
| 787 Configuration exec(Statement statement, State state) => | 813 Configuration exec(Statement statement, State state) => |
| 788 statement.accept1(this, state); | 814 statement.accept1(this, state); |
| 789 Configuration eval(Expression expression, ExpressionConfiguration config) => | 815 Configuration eval(Expression expression, ExpressionConfiguration config) => |
| 790 evaluator.eval(expression, config); | 816 evaluator.eval(expression, config); |
| 817 Configuration evalArgs( | |
| 818 List<ArgumentExpression> args, Environment env, Continuation cont) => | |
| 819 evaluator.evalArgs(args, env, cont); | |
| 791 | 820 |
| 792 Configuration defaultStatement(Statement node, State state) { | 821 Configuration defaultStatement(Statement node, State state) { |
| 793 throw notImplemented( | 822 throw notImplemented( |
| 794 m: "Execution is not implemented for statement:\n$node "); | 823 m: "Execution is not implemented for statement:\n$node "); |
| 795 } | 824 } |
| 796 | 825 |
| 797 Configuration visitInvalidStatement(InvalidStatement node, State state) { | 826 Configuration visitInvalidStatement(InvalidStatement node, State state) { |
| 798 throw "Invalid statement at ${node.location}"; | 827 throw "Invalid statement at ${node.location}"; |
| 799 } | 828 } |
| 800 | 829 |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1103 | 1132 |
| 1104 class NullValue extends LiteralValue { | 1133 class NullValue extends LiteralValue { |
| 1105 Object get value => null; | 1134 Object get value => null; |
| 1106 | 1135 |
| 1107 const NullValue(); | 1136 const NullValue(); |
| 1108 } | 1137 } |
| 1109 | 1138 |
| 1110 notImplemented({String m, Object obj}) { | 1139 notImplemented({String m, Object obj}) { |
| 1111 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); | 1140 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); |
| 1112 } | 1141 } |
| 1142 | |
| 1143 // ------------------------------------------------------------------------ | |
| 1144 // INTERNAL FUNCTIONS | |
| 1145 // ------------------------------------------------------------------------ | |
| 1146 /// Creates a list of all argument expressions to be evaluated for the | |
| 1147 /// invocation of the provided [FunctionNode] containing the actual arguments | |
| 1148 /// and the optional argument initializers. | |
| 1149 List<ArgumentExpression> _createArgumentExpressionList( | |
| 1150 Arguments providedArgs, FunctionNode fun) { | |
| 1151 List<ArgumentExpression> args = <ArgumentExpression>[]; | |
| 1152 // Add positional arguments expressions. | |
| 1153 args.addAll(providedArgs.positional | |
| 1154 .map((Expression e) => new PositionalArgumentExpression(e))); | |
| 1155 | |
| 1156 // Add optional positional argument initializers. | |
| 1157 for (int i = providedArgs.positional.length; | |
| 1158 i < fun.positionalParameters.length; | |
| 1159 i++) { | |
| 1160 args.add(new PositionalArgumentExpression( | |
| 1161 fun.positionalParameters[i].initializer)); | |
| 1162 } | |
| 1163 | |
| 1164 Map<String, NamedArgumentExpression> namedFormals = new Map.fromIterable( | |
| 1165 fun.namedParameters, | |
| 1166 key: (VariableDeclaration vd) => vd.name, | |
| 1167 value: (VariableDeclaration vd) => | |
| 1168 new NamedArgumentExpression(vd.name, vd.initializer)); | |
| 1169 | |
| 1170 // Add named expressions. | |
| 1171 for (int i = 0; i < providedArgs.named.length; i++) { | |
| 1172 var current = providedArgs.named[i]; | |
| 1173 args.add(new NamedArgumentExpression(current.name, current.value)); | |
| 1174 namedFormals.remove(current.name); | |
| 1175 } | |
| 1176 | |
| 1177 // Add missing optional named initializers. | |
| 1178 args.addAll(namedFormals.values); | |
| 1179 | |
| 1180 return args; | |
| 1181 } | |
| OLD | NEW |