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 String get name; | |
| 386 Expression get expression; | |
| 387 } | |
| 388 | |
| 389 class PositionalArgumentExpression extends ArgumentExpression { | |
| 390 String get name => throw 'PositionalArgumentExpression has no name'; | |
|
Dmitry Stefantsov
2017/05/10 08:08:49
It's not clear why we define "name" getter in Argu
zhivkag
2017/05/10 08:27:07
I initially intended to have name for both, but fi
| |
| 391 final Expression expression; | |
| 392 | |
| 393 PositionalArgumentExpression(this.expression); | |
| 394 } | |
| 395 | |
| 396 class NamedArgumentExpression extends ArgumentExpression { | |
| 397 final String name; | |
| 398 final Expression expression; | |
| 399 | |
| 400 NamedArgumentExpression(this.name, this.expression); | |
| 401 } | |
| 402 | |
| 403 abstract class ArgumentValue { | |
| 404 Value get value; | |
| 405 } | |
| 406 | |
| 407 class PositionalArgumentValue extends ArgumentValue { | |
| 408 final Value value; | |
| 409 | |
| 410 PositionalArgumentValue(this.value); | |
| 411 } | |
| 412 | |
| 413 class NamedArgumentValue extends ArgumentValue { | |
| 414 final String name; | |
| 415 final Value value; | |
| 416 | |
| 417 NamedArgumentValue(this.name, this.value); | |
| 418 } | |
| 419 | |
| 420 abstract class Continuation {} | |
| 421 | |
| 422 // ------------------------------------------------------------------------ | |
| 423 // EXPRESSION CONTINUATIONS | |
| 424 // ------------------------------------------------------------------------ | |
| 425 | |
| 350 /// Represents an expression continuation. | 426 /// Represents an expression continuation. |
| 351 abstract class ExpressionContinuation { | 427 abstract class ExpressionContinuation extends Continuation { |
| 352 Configuration call(Value v); | 428 Configuration call(Value v); |
| 353 } | 429 } |
| 354 | 430 |
| 355 /// Represents a continuation that returns the next [StatementConfiguration] | 431 /// Represents a continuation that returns the next [StatementConfiguration] |
| 356 /// to be executed. | 432 /// to be executed. |
| 357 class ExpressionStatementContinuation extends ExpressionContinuation { | 433 class ExpressionStatementContinuation extends ExpressionContinuation { |
| 358 final StatementConfiguration configuration; | 434 final StatementConfiguration configuration; |
| 359 | 435 |
| 360 ExpressionStatementContinuation(this.configuration); | 436 ExpressionStatementContinuation(this.configuration); |
| 361 | 437 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 414 Configuration call(Value v) { | 490 Configuration call(Value v) { |
| 415 Setter setter = receiver.class_.lookupSetter(name); | 491 Setter setter = receiver.class_.lookupSetter(name); |
| 416 setter(receiver, v); | 492 setter(receiver, v); |
| 417 return new ContinuationConfiguration(continuation, v); | 493 return new ContinuationConfiguration(continuation, v); |
| 418 } | 494 } |
| 419 } | 495 } |
| 420 | 496 |
| 421 /// Represents a continuation to be called after the evaluation of an actual | 497 /// Represents a continuation to be called after the evaluation of an actual |
| 422 /// argument for function invocation. | 498 /// argument for function invocation. |
| 423 /// TODO: Add checks for validation of arguments according to spec. | 499 /// TODO: Add checks for validation of arguments according to spec. |
| 424 class ActualArgumentsContinuation extends ExpressionContinuation { | 500 class ActualArgumentsContinuation extends Continuation { |
| 425 final Arguments arguments; | 501 final ArgumentExpression currentArgument; |
| 426 final FunctionNode functionNode; | 502 final List<ArgumentExpression> arguments; |
| 427 final Environment environment; | 503 final Environment environment; |
| 428 final ExpressionContinuation continuation; | 504 final ApplicationContinuation applicationContinuation; |
| 429 | 505 |
| 430 final List<Value> _positional = <Value>[]; | 506 ActualArgumentsContinuation(this.currentArgument, this.arguments, |
| 431 int _currentPositional = 0; | 507 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 | 508 |
| 438 Configuration call(Value v) { | 509 Configuration call(Value v) { |
| 439 if (_currentPositional < arguments.positional.length) { | 510 ArgumentValue argumentValue; |
| 440 _positional.add(v); | 511 if (currentArgument is NamedArgumentExpression) { |
| 441 _currentPositional++; | 512 argumentValue = new NamedArgumentValue(currentArgument.name, v); |
| 442 } else { | 513 } else { |
| 443 assert(_currentNamed < arguments.named.length); | 514 argumentValue = new PositionalArgumentValue(v); |
| 444 String name = arguments.named[_currentNamed].name; | |
| 445 _named[name] = v; | |
| 446 _currentNamed++; | |
| 447 } | 515 } |
| 448 | 516 |
| 449 return createCurrentConfiguration(); | 517 return new ArgumentsConfiguration(arguments, environment, |
| 450 } | 518 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 } | 519 } |
| 471 } | 520 } |
| 472 | 521 |
| 473 class OptionalArgumentsContinuation extends ExpressionContinuation { | 522 /// Represents the continuation called after the evaluation of argument |
| 474 final List<Value> positional; | 523 /// expressions. |
| 475 final Map<String, Value> named; | 524 abstract class ApplicationContinuation extends Continuation { |
| 476 final FunctionNode functionNode; | 525 Configuration call(List<ArgumentValue> args); |
| 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 | 526 |
| 541 /// Creates an environment binding actual argument values to formal parameters | 527 /// Creates an environment binding actual argument values to formal parameters |
| 542 /// of the function in a new environment, which is used to execute the | 528 /// of the function in a new environment, which is used to execute the |
| 543 /// body od the function. | 529 /// body od the function. |
| 544 Environment _createEnvironment() { | 530 static Environment createEnvironment( |
| 531 FunctionNode function, List<ArgumentValue> args) { | |
| 545 Environment newEnv = new Environment.empty(); | 532 Environment newEnv = new Environment.empty(); |
| 533 List<PositionalArgumentValue> positional = args.reversed | |
| 534 .where((ArgumentValue av) => av is PositionalArgumentValue) | |
| 535 .toList(); | |
| 536 | |
| 546 // Add positional parameters. | 537 // Add positional parameters. |
| 547 for (int i = 0; i < positional.length; ++i) { | 538 for (int i = 0; i < positional.length; ++i) { |
| 548 newEnv.expand(functionNode.positionalParameters[i], positional[i]); | 539 newEnv.expand(function.positionalParameters[i], positional[i].value); |
| 549 } | 540 } |
| 541 | |
| 542 Map<String, Value> named = new Map.fromIterable( | |
| 543 args.where((ArgumentValue av) => av is NamedArgumentValue), | |
| 544 key: (NamedArgumentValue av) => av.name, | |
| 545 value: (NamedArgumentValue av) => av.value); | |
| 546 | |
| 550 // Add named parameters. | 547 // Add named parameters. |
| 551 for (VariableDeclaration v in functionNode.namedParameters) { | 548 for (VariableDeclaration v in function.namedParameters) { |
| 552 newEnv.expand(v, named[v.name.toString()]); | 549 newEnv.expand(v, named[v.name.toString()]); |
| 553 } | 550 } |
| 554 | 551 |
| 555 return newEnv; | 552 return newEnv; |
| 556 } | 553 } |
| 557 } | 554 } |
| 558 | 555 |
| 556 /// Represents the application continuation for static invocation. | |
| 557 class StaticInvocationApplication extends ApplicationContinuation { | |
| 558 final FunctionNode function; | |
| 559 final ExpressionContinuation continuation; | |
| 560 | |
| 561 StaticInvocationApplication(this.function, this.continuation); | |
| 562 | |
| 563 Configuration call(List<ArgumentValue> args) { | |
| 564 Environment functionEnv = | |
| 565 ApplicationContinuation.createEnvironment(function, args); | |
| 566 | |
| 567 State bodyState = new State.initial() | |
| 568 .withExpressionContinuation(continuation) | |
| 569 .withConfiguration(new ExitConfiguration(continuation)) | |
| 570 .withEnvironment(functionEnv); | |
| 571 return new StatementConfiguration(function.body, bodyState); | |
| 572 } | |
| 573 } | |
| 574 | |
| 575 /// Represents the application continuation called after the evaluation of all | |
| 576 /// argument expressions for an invocation. | |
| 577 class ArgumentValueApplication extends ApplicationContinuation { | |
| 578 final ArgumentValue value; | |
| 579 final ApplicationContinuation applicationContinuation; | |
| 580 | |
| 581 ArgumentValueApplication(this.value, this.applicationContinuation); | |
| 582 | |
| 583 Configuration call(List<ArgumentValue> args) { | |
| 584 args.add(value); | |
| 585 return new ArgumentContinuationConfiguration(applicationContinuation, args); | |
| 586 } | |
| 587 } | |
| 588 | |
| 559 class MethodInvocationContinuation extends ExpressionContinuation { | 589 class MethodInvocationContinuation extends ExpressionContinuation { |
| 560 final Arguments arguments; | 590 final Arguments arguments; |
| 561 final Name methodName; | 591 final Name methodName; |
| 562 final Environment environment; | 592 final Environment environment; |
| 563 final ExpressionContinuation continuation; | 593 final ExpressionContinuation continuation; |
| 564 | 594 |
| 565 MethodInvocationContinuation( | 595 MethodInvocationContinuation( |
| 566 this.arguments, this.methodName, this.environment, this.continuation); | 596 this.arguments, this.methodName, this.environment, this.continuation); |
| 567 | 597 |
| 568 Configuration call(Value receiver) { | 598 Configuration call(Value receiver) { |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 void trampolinedExecution(Configuration configuration) { | 811 void trampolinedExecution(Configuration configuration) { |
| 782 while (configuration != null) { | 812 while (configuration != null) { |
| 783 configuration = configuration.step(this); | 813 configuration = configuration.step(this); |
| 784 } | 814 } |
| 785 } | 815 } |
| 786 | 816 |
| 787 Configuration exec(Statement statement, State state) => | 817 Configuration exec(Statement statement, State state) => |
| 788 statement.accept1(this, state); | 818 statement.accept1(this, state); |
| 789 Configuration eval(Expression expression, ExpressionConfiguration config) => | 819 Configuration eval(Expression expression, ExpressionConfiguration config) => |
| 790 evaluator.eval(expression, config); | 820 evaluator.eval(expression, config); |
| 821 Configuration evalArgs( | |
| 822 List<ArgumentExpression> args, Environment env, Continuation cont) => | |
| 823 evaluator.evalArgs(args, env, cont); | |
| 791 | 824 |
| 792 Configuration defaultStatement(Statement node, State state) { | 825 Configuration defaultStatement(Statement node, State state) { |
| 793 throw notImplemented( | 826 throw notImplemented( |
| 794 m: "Execution is not implemented for statement:\n$node "); | 827 m: "Execution is not implemented for statement:\n$node "); |
| 795 } | 828 } |
| 796 | 829 |
| 797 Configuration visitInvalidStatement(InvalidStatement node, State state) { | 830 Configuration visitInvalidStatement(InvalidStatement node, State state) { |
| 798 throw "Invalid statement at ${node.location}"; | 831 throw "Invalid statement at ${node.location}"; |
| 799 } | 832 } |
| 800 | 833 |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1103 | 1136 |
| 1104 class NullValue extends LiteralValue { | 1137 class NullValue extends LiteralValue { |
| 1105 Object get value => null; | 1138 Object get value => null; |
| 1106 | 1139 |
| 1107 const NullValue(); | 1140 const NullValue(); |
| 1108 } | 1141 } |
| 1109 | 1142 |
| 1110 notImplemented({String m, Object obj}) { | 1143 notImplemented({String m, Object obj}) { |
| 1111 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); | 1144 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); |
| 1112 } | 1145 } |
| 1146 | |
| 1147 // ------------------------------------------------------------------------ | |
| 1148 // INTERNAL FUNCTIONS | |
| 1149 // ------------------------------------------------------------------------ | |
| 1150 /// Creates a list of all argument expressions to be evaluated for the | |
| 1151 /// invocation of the provided [FunctionNode] containing the actual arguments | |
| 1152 /// and the optional argument initializers. | |
| 1153 List<ArgumentExpression> _createArgumentExpressionList( | |
| 1154 Arguments providedArgs, FunctionNode fun) { | |
| 1155 List<ArgumentExpression> args = <ArgumentExpression>[]; | |
| 1156 // Add positional arguments expressions. | |
| 1157 args.addAll(providedArgs.positional | |
| 1158 .map((Expression e) => new PositionalArgumentExpression(e))); | |
| 1159 | |
| 1160 // Add optional positional argument initializers. | |
| 1161 for (int i = providedArgs.positional.length; | |
| 1162 i < fun.positionalParameters.length; | |
| 1163 i++) { | |
| 1164 args.add(new PositionalArgumentExpression( | |
| 1165 fun.positionalParameters[i].initializer)); | |
| 1166 } | |
| 1167 | |
| 1168 Map<String, NamedArgumentExpression> namedFormals = new Map.fromIterable( | |
| 1169 fun.namedParameters, | |
| 1170 key: (VariableDeclaration vd) => vd.name, | |
| 1171 value: (VariableDeclaration vd) => | |
| 1172 new NamedArgumentExpression(vd.name, vd.initializer)); | |
| 1173 | |
| 1174 // Add named expressions. | |
| 1175 for (int i = 0; i < providedArgs.named.length; i++) { | |
| 1176 var current = providedArgs.named[i]; | |
| 1177 args.add(new NamedArgumentExpression(current.name, current.value)); | |
| 1178 namedFormals.remove(current.name); | |
| 1179 } | |
| 1180 | |
| 1181 // Add missing optional named initializers. | |
| 1182 args.addAll(namedFormals.values); | |
| 1183 | |
| 1184 return args; | |
| 1185 } | |
| OLD | NEW |