Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 | 4 |
| 5 library backend_ast_emitter; | 5 library backend_ast_emitter; |
| 6 | 6 |
| 7 import '../tree_ir/tree_ir_nodes.dart' as tree; | 7 import '../tree_ir/tree_ir_nodes.dart' as tree; |
| 8 import 'backend_ast_nodes.dart'; | 8 import 'backend_ast_nodes.dart'; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 } | 277 } |
| 278 } | 278 } |
| 279 | 279 |
| 280 // Add constant declarations. | 280 // Add constant declarations. |
| 281 List<VariableDeclaration> constants = <VariableDeclaration>[]; | 281 List<VariableDeclaration> constants = <VariableDeclaration>[]; |
| 282 for (ConstDeclaration constDecl in definition.localConstants) { | 282 for (ConstDeclaration constDecl in definition.localConstants) { |
| 283 if (!context.constantNames.containsKey(constDecl.element)) { | 283 if (!context.constantNames.containsKey(constDecl.element)) { |
| 284 continue; // Discard unused constants declarations. | 284 continue; // Discard unused constants declarations. |
| 285 } | 285 } |
| 286 String name = context.getConstantName(constDecl.element); | 286 String name = context.getConstantName(constDecl.element); |
| 287 Expression value = emitConstant(constDecl.expression, context); | 287 Expression value = |
| 288 ConstantEmitter.createExpression(constDecl.expression, context); | |
| 288 VariableDeclaration decl = new VariableDeclaration(name, value); | 289 VariableDeclaration decl = new VariableDeclaration(name, value); |
| 289 decl.element = constDecl.element; | 290 decl.element = constDecl.element; |
| 290 constants.add(decl); | 291 constants.add(decl); |
| 291 } | 292 } |
| 292 | 293 |
| 293 List<Statement> bodyParts = []; | 294 List<Statement> bodyParts = []; |
| 294 if (constants.length > 0) { | 295 if (constants.length > 0) { |
| 295 bodyParts.add(new VariableDeclarations(constants, isConst: true)); | 296 bodyParts.add(new VariableDeclarations(constants, isConst: true)); |
| 296 } | 297 } |
| 297 if (context.variables.length > 0) { | 298 if (context.variables.length > 0) { |
| 298 bodyParts.add(new VariableDeclarations(context.variables)); | 299 bodyParts.add(new VariableDeclarations(context.variables)); |
| 299 } | 300 } |
| 300 bodyParts.addAll(context.statements); | 301 bodyParts.addAll(context.statements); |
| 301 | 302 |
| 302 body = new Block(bodyParts); | 303 body = new Block(bodyParts); |
| 303 } | 304 } |
| 304 FunctionType functionType = context.currentElement.type; | 305 FunctionType functionType = context.currentElement.type; |
| 305 | 306 |
| 306 return new FunctionExpression( | 307 return new FunctionExpression( |
| 307 parameters, | 308 parameters, |
| 308 body, | 309 body, |
| 309 name: context.currentElement.name, | 310 name: context.currentElement.name, |
| 310 returnType: emitOptionalType(functionType.returnType), | 311 returnType: TypeGenerator.createOptionalType(functionType.returnType), |
| 311 isGetter: context.currentElement.isGetter, | 312 isGetter: context.currentElement.isGetter, |
| 312 isSetter: context.currentElement.isSetter) | 313 isSetter: context.currentElement.isSetter) |
| 313 ..element = context.currentElement; | 314 ..element = context.currentElement; |
| 314 } | 315 } |
| 315 | 316 |
| 316 /// TODO(johnniwinther): Remove this when issue 21283 has been resolved. | |
| 317 int pseudoNameCounter = 0; | |
| 318 | |
| 319 Parameter emitParameter(DartType type, | |
| 320 BuilderContext<Statement> context, | |
| 321 {String name, | |
| 322 Element element, | |
| 323 ConstantExpression defaultValue}) { | |
| 324 if (name == null && element != null) { | |
| 325 name = element.name; | |
| 326 } | |
| 327 if (name == null) { | |
| 328 name = '_${pseudoNameCounter++}'; | |
| 329 } | |
| 330 Parameter parameter; | |
| 331 if (type.isFunctionType) { | |
| 332 FunctionType functionType = type; | |
| 333 TypeAnnotation returnType = emitOptionalType(functionType.returnType); | |
| 334 Parameters innerParameters = | |
| 335 emitParametersFromType(functionType, context); | |
| 336 parameter = new Parameter.function(name, returnType, innerParameters); | |
| 337 } else { | |
| 338 TypeAnnotation typeAnnotation = emitOptionalType(type); | |
| 339 parameter = new Parameter(name, type: typeAnnotation); | |
| 340 } | |
| 341 parameter.element = element; | |
| 342 if (defaultValue != null && !defaultValue.value.isNull) { | |
| 343 parameter.defaultValue = emitConstant(defaultValue, context); | |
| 344 } | |
| 345 return parameter; | |
| 346 } | |
| 347 | |
| 348 Parameters emitParametersFromType(FunctionType functionType, | |
| 349 BuilderContext<Statement> context) { | |
| 350 if (functionType.namedParameters.isEmpty) { | |
| 351 return new Parameters( | |
| 352 emitParameters(functionType.parameterTypes, context), | |
| 353 emitParameters(functionType.optionalParameterTypes, context), | |
| 354 false); | |
| 355 } else { | |
| 356 return new Parameters( | |
| 357 emitParameters(functionType.parameterTypes, context), | |
| 358 emitParameters(functionType.namedParameterTypes, context, | |
| 359 names: functionType.namedParameters), | |
| 360 true); | |
| 361 } | |
| 362 } | |
| 363 | |
| 364 List<Parameter> emitParameters( | |
| 365 Iterable<DartType> parameterTypes, | |
| 366 BuilderContext<Statement> context, | |
| 367 {Iterable<String> names: const <String>[], | |
| 368 Iterable<ConstantExpression> defaultValues: const <ConstantExpression>[], | |
| 369 Iterable<Element> elements: const <Element>[]}) { | |
| 370 Iterator<String> name = names.iterator; | |
| 371 Iterator<ConstantExpression> defaultValue = defaultValues.iterator; | |
| 372 Iterator<Element> element = elements.iterator; | |
| 373 return parameterTypes.map((DartType type) { | |
| 374 name.moveNext(); | |
| 375 defaultValue.moveNext(); | |
| 376 element.moveNext(); | |
| 377 return emitParameter(type, context, | |
| 378 name: name.current, | |
| 379 defaultValue: defaultValue.current, | |
| 380 element: element.current); | |
| 381 }).toList(); | |
| 382 } | |
| 383 | |
| 384 /// Emits parameters that are not nested inside other parameters. | 317 /// Emits parameters that are not nested inside other parameters. |
| 385 /// Root parameters can have default values, while inner parameters cannot. | 318 /// Root parameters can have default values, while inner parameters cannot. |
| 386 Parameters emitRootParameters(tree.FunctionDefinition function, | 319 Parameters emitRootParameters(tree.FunctionDefinition function, |
| 387 BuilderContext<Statement> context) { | 320 BuilderContext<Statement> context) { |
| 388 FunctionType functionType = function.element.type; | 321 FunctionType functionType = function.element.type; |
| 389 List<Parameter> required = emitParameters( | 322 List<Parameter> required = TypeGenerator.createParameters( |
| 390 functionType.parameterTypes, context, | 323 functionType.parameterTypes, |
| 324 context: context, | |
| 391 elements: function.parameters.map((p) => p.element)); | 325 elements: function.parameters.map((p) => p.element)); |
| 392 bool optionalParametersAreNamed = !functionType.namedParameters.isEmpty; | 326 bool optionalParametersAreNamed = !functionType.namedParameters.isEmpty; |
| 393 List<Parameter> optional = emitParameters( | 327 List<Parameter> optional = TypeGenerator.createParameters( |
| 394 optionalParametersAreNamed | 328 optionalParametersAreNamed |
| 395 ? functionType.namedParameterTypes | 329 ? functionType.namedParameterTypes |
| 396 : functionType.optionalParameterTypes, | 330 : functionType.optionalParameterTypes, |
| 397 context, | 331 context: context, |
| 398 defaultValues: function.defaultParameterValues, | 332 defaultValues: function.defaultParameterValues, |
| 399 elements: function.parameters.skip(required.length) | 333 elements: function.parameters.skip(required.length) |
| 400 .map((p) => p.element)); | 334 .map((p) => p.element)); |
| 401 return new Parameters(required, optional, optionalParametersAreNamed); | 335 return new Parameters(required, optional, optionalParametersAreNamed); |
| 402 } | 336 } |
| 403 | 337 |
| 404 /// True if the two expressions are a reference to the same variable. | 338 /// True if the two expressions are a reference to the same variable. |
| 405 bool isSameVariable(Receiver e1, Receiver e2) { | 339 bool isSameVariable(Receiver e1, Receiver e2) { |
| 406 return e1 is Identifier && | 340 return e1 is Identifier && |
| 407 e2 is Identifier && | 341 e2 is Identifier && |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 Block body = visitInSubContext(stmt.body, context, fallthrough: stmt); | 527 Block body = visitInSubContext(stmt.body, context, fallthrough: stmt); |
| 594 Statement statement = new While(condition, body); | 528 Statement statement = new While(condition, body); |
| 595 addLabeledStatement(stmt.label, statement, context); | 529 addLabeledStatement(stmt.label, statement, context); |
| 596 | 530 |
| 597 visitStatement(stmt.next, context); | 531 visitStatement(stmt.next, context); |
| 598 } | 532 } |
| 599 | 533 |
| 600 @override | 534 @override |
| 601 Expression visitConstant(tree.Constant exp, | 535 Expression visitConstant(tree.Constant exp, |
| 602 BuilderContext<Statement> context) { | 536 BuilderContext<Statement> context) { |
| 603 return emitConstant(exp.expression, context); | 537 return ConstantEmitter.createExpression(exp.expression, context); |
| 604 } | 538 } |
| 605 | 539 |
| 606 @override | 540 @override |
| 607 Expression visitThis(tree.This exp, | 541 Expression visitThis(tree.This exp, |
| 608 BuilderContext<Statement> context) { | 542 BuilderContext<Statement> context) { |
| 609 return new This(); | 543 return new This(); |
| 610 } | 544 } |
| 611 | 545 |
| 612 @override | 546 @override |
| 613 Expression visitReifyTypeVar(tree.ReifyTypeVar exp, | 547 Expression visitReifyTypeVar(tree.ReifyTypeVar exp, |
| 614 BuilderContext<Statement> context) { | 548 BuilderContext<Statement> context) { |
| 615 return new ReifyTypeVar(exp.typeVariable.name) | 549 return new ReifyTypeVar(exp.typeVariable.name) |
| 616 ..element = exp.typeVariable; | 550 ..element = exp.typeVariable; |
| 617 } | 551 } |
| 618 | 552 |
| 619 List<Expression> visitExpressions(List<tree.Expression> expressions, | 553 List<Expression> visitExpressions(List<tree.Expression> expressions, |
| 620 BuilderContext<Statement> context) { | 554 BuilderContext<Statement> context) { |
| 621 return expressions.map((expression) => visitExpression(expression, context)) | 555 return expressions.map((expression) => visitExpression(expression, context)) |
| 622 .toList(growable: false); | 556 .toList(growable: false); |
| 623 } | 557 } |
| 624 | 558 |
| 625 @override | 559 @override |
| 626 Expression visitLiteralList(tree.LiteralList exp, | 560 Expression visitLiteralList(tree.LiteralList exp, |
| 627 BuilderContext<Statement> context) { | 561 BuilderContext<Statement> context) { |
| 628 return new LiteralList(visitExpressions(exp.values, context), | 562 return new LiteralList(visitExpressions(exp.values, context), |
| 629 typeArgument: emitOptionalType(exp.type.typeArguments.single)); | 563 typeArgument: |
| 564 TypeGenerator.createOptionalType(exp.type.typeArguments.single)); | |
| 630 } | 565 } |
| 631 | 566 |
| 632 @override | 567 @override |
| 633 Expression visitLiteralMap(tree.LiteralMap exp, | 568 Expression visitLiteralMap(tree.LiteralMap exp, |
| 634 BuilderContext<Statement> context) { | 569 BuilderContext<Statement> context) { |
| 635 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( | 570 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( |
| 636 exp.entries.length, | 571 exp.entries.length, |
| 637 (i) => new LiteralMapEntry(visitExpression(exp.entries[i].key, context), | 572 (i) => new LiteralMapEntry( |
| 638 visitExpression(exp.entries[i].value, context ))); | 573 visitExpression(exp.entries[i].key, context), |
| 574 visitExpression(exp.entries[i].value, context))); | |
| 639 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw | 575 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw |
| 640 ? null | 576 ? null |
| 641 : exp.type.typeArguments.map(createTypeAnnotation) | 577 : exp.type.typeArguments.map(TypeGenerator.createType) |
| 642 .toList(growable: false); | 578 .toList(growable: false); |
| 643 return new LiteralMap(entries, typeArguments: typeArguments); | 579 return new LiteralMap(entries, typeArguments: typeArguments); |
| 644 } | 580 } |
| 645 | 581 |
| 646 @override | 582 @override |
| 647 Expression visitTypeOperator(tree.TypeOperator exp, | 583 Expression visitTypeOperator(tree.TypeOperator exp, |
| 648 BuilderContext<Statement> context) { | 584 BuilderContext<Statement> context) { |
| 649 return new TypeOperator(visitExpression(exp.receiver, context), | 585 return new TypeOperator(visitExpression(exp.receiver, context), |
| 650 exp.operator, | 586 exp.operator, |
| 651 createTypeAnnotation(exp.type)); | 587 TypeGenerator.createType(exp.type)); |
| 652 } | 588 } |
| 653 | 589 |
| 654 List<Argument> emitArguments(tree.Invoke exp, | 590 List<Argument> emitArguments(tree.Invoke exp, |
| 655 BuilderContext<Statement> context) { | 591 BuilderContext<Statement> context) { |
| 656 List<tree.Expression> args = exp.arguments; | 592 List<tree.Expression> args = exp.arguments; |
| 657 int positionalArgumentCount = exp.selector.positionalArgumentCount; | 593 int positionalArgumentCount = exp.selector.positionalArgumentCount; |
| 658 List<Argument> result = new List<Argument>.generate(positionalArgumentCount, | 594 List<Argument> result = new List<Argument>.generate(positionalArgumentCount, |
| 659 (i) => visitExpression(exp.arguments[i], context)); | 595 (i) => visitExpression(exp.arguments[i], context)); |
| 660 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { | 596 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { |
| 661 result.add(new NamedArgument(exp.selector.namedArguments[i], | 597 result.add(new NamedArgument(exp.selector.namedArguments[i], |
| 662 visitExpression(exp.arguments[positionalArgumentCount + i], context))) ; | 598 visitExpression( |
|
sigurdm
2014/12/08 13:02:30
Is there trailing whitespace here? It looks like t
Johnni Winther
2014/12/10 08:47:54
No. It's clean.
| |
| 599 exp.arguments[positionalArgumentCount + i], context))); | |
| 663 } | 600 } |
| 664 return result; | 601 return result; |
| 665 } | 602 } |
| 666 | 603 |
| 667 @override | 604 @override |
| 668 Expression visitInvokeStatic(tree.InvokeStatic exp, | 605 Expression visitInvokeStatic(tree.InvokeStatic exp, |
| 669 BuilderContext<Statement> context) { | 606 BuilderContext<Statement> context) { |
| 670 switch (exp.selector.kind) { | 607 switch (exp.selector.kind) { |
| 671 case SelectorKind.GETTER: | 608 case SelectorKind.GETTER: |
| 672 return new Identifier(exp.target.name)..element = exp.target; | 609 return new Identifier(exp.target.name)..element = exp.target; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 BuilderContext<Statement> context) { | 676 BuilderContext<Statement> context) { |
| 740 return emitMethodCall(exp, new SuperReceiver(), context); | 677 return emitMethodCall(exp, new SuperReceiver(), context); |
| 741 } | 678 } |
| 742 | 679 |
| 743 @override | 680 @override |
| 744 Expression visitInvokeConstructor(tree.InvokeConstructor exp, | 681 Expression visitInvokeConstructor(tree.InvokeConstructor exp, |
| 745 BuilderContext<Statement> context) { | 682 BuilderContext<Statement> context) { |
| 746 List args = emitArguments(exp, context); | 683 List args = emitArguments(exp, context); |
| 747 FunctionElement constructor = exp.target; | 684 FunctionElement constructor = exp.target; |
| 748 String name = constructor.name.isEmpty ? null : constructor.name; | 685 String name = constructor.name.isEmpty ? null : constructor.name; |
| 749 return new CallNew(createTypeAnnotation(exp.type), | 686 return new CallNew(TypeGenerator.createType(exp.type), |
| 750 args, | 687 args, |
| 751 constructorName: name, | 688 constructorName: name, |
| 752 isConst: exp.constant != null) | 689 isConst: exp.constant != null) |
| 753 ..constructor = constructor | 690 ..constructor = constructor |
| 754 ..dartType = exp.type; | 691 ..dartType = exp.type; |
| 755 } | 692 } |
| 756 | 693 |
| 757 @override | 694 @override |
| 758 Expression visitConcatenateStrings(tree.ConcatenateStrings exp, | 695 Expression visitConcatenateStrings(tree.ConcatenateStrings exp, |
| 759 BuilderContext<Statement> context) { | 696 BuilderContext<Statement> context) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 806 BuilderContext<Statement> context) { | 743 BuilderContext<Statement> context) { |
| 807 assert(context.variableNames[node.variable] == null); | 744 assert(context.variableNames[node.variable] == null); |
| 808 String name = context.getVariableName(node.variable); | 745 String name = context.getVariableName(node.variable); |
| 809 FunctionExpression inner = makeSubFunction(node.definition, context); | 746 FunctionExpression inner = makeSubFunction(node.definition, context); |
| 810 inner.name = name; | 747 inner.name = name; |
| 811 FunctionDeclaration decl = new FunctionDeclaration(inner); | 748 FunctionDeclaration decl = new FunctionDeclaration(inner); |
| 812 context.declaredVariables.add(node.variable); | 749 context.declaredVariables.add(node.variable); |
| 813 context.addStatement(decl); | 750 context.addStatement(decl); |
| 814 visitStatement(node.next, context); | 751 visitStatement(node.next, context); |
| 815 } | 752 } |
| 816 | |
| 817 Expression emitConstant(ConstantExpression exp, | |
| 818 BuilderContext<Statement> context) { | |
| 819 return const ConstantEmitter().visit(exp, context); | |
| 820 } | |
| 821 } | 753 } |
| 822 | 754 |
| 823 /// Like [createTypeAnnotation] except the dynamic type is converted to null. | 755 class TypeGenerator { |
|
sigurdm
2014/12/08 13:02:29
All the methods are static. Do we need the class a
Johnni Winther
2014/12/10 08:47:54
We don't need it but I wanted to group all methods
| |
| 824 TypeAnnotation emitOptionalType(DartType type) { | 756 |
| 825 if (type.treatAsDynamic) { | 757 /// TODO(johnniwinther): Remove this when issue 21283 has been resolved. |
| 826 return null; | 758 static int pseudoNameCounter = 0; |
| 827 } else { | 759 |
| 828 return createTypeAnnotation(type); | 760 static Parameter emitParameter(DartType type, |
| 761 BuilderContext<Statement> context, | |
| 762 {String name, | |
| 763 Element element, | |
| 764 ConstantExpression defaultValue}) { | |
| 765 if (name == null && element != null) { | |
| 766 name = element.name; | |
| 767 } | |
| 768 if (name == null) { | |
| 769 name = '_${pseudoNameCounter++}'; | |
| 770 } | |
| 771 Parameter parameter; | |
| 772 if (type.isFunctionType) { | |
| 773 FunctionType functionType = type; | |
| 774 TypeAnnotation returnType = createOptionalType(functionType.returnType); | |
| 775 Parameters innerParameters = | |
| 776 createParametersFromType(functionType); | |
| 777 parameter = new Parameter.function(name, returnType, innerParameters); | |
| 778 } else { | |
| 779 TypeAnnotation typeAnnotation = createOptionalType(type); | |
| 780 parameter = new Parameter(name, type: typeAnnotation); | |
| 781 } | |
| 782 parameter.element = element; | |
| 783 if (defaultValue != null && !defaultValue.value.isNull) { | |
| 784 parameter.defaultValue = | |
| 785 ConstantEmitter.createExpression(defaultValue, context); | |
| 786 } | |
| 787 return parameter; | |
| 829 } | 788 } |
| 789 | |
| 790 static Parameters createParametersFromType(FunctionType functionType) { | |
| 791 pseudoNameCounter = 0; | |
| 792 if (functionType.namedParameters.isEmpty) { | |
| 793 return new Parameters( | |
| 794 createParameters(functionType.parameterTypes), | |
| 795 createParameters(functionType.optionalParameterTypes), | |
| 796 false); | |
| 797 } else { | |
| 798 return new Parameters( | |
| 799 createParameters(functionType.parameterTypes), | |
| 800 createParameters(functionType.namedParameterTypes, | |
| 801 names: functionType.namedParameters), | |
| 802 true); | |
| 803 } | |
| 804 } | |
| 805 | |
| 806 static List<Parameter> createParameters( | |
| 807 Iterable<DartType> parameterTypes, | |
| 808 {BuilderContext<Statement> context, | |
| 809 Iterable<String> names: const <String>[], | |
| 810 Iterable<ConstantExpression> defaultValues: const <ConstantExpression>[], | |
| 811 Iterable<Element> elements: const <Element>[]}) { | |
| 812 Iterator<String> name = names.iterator; | |
| 813 Iterator<ConstantExpression> defaultValue = defaultValues.iterator; | |
| 814 Iterator<Element> element = elements.iterator; | |
| 815 return parameterTypes.map((DartType type) { | |
| 816 name.moveNext(); | |
| 817 defaultValue.moveNext(); | |
| 818 element.moveNext(); | |
| 819 return emitParameter(type, context, | |
| 820 name: name.current, | |
| 821 defaultValue: defaultValue.current, | |
| 822 element: element.current); | |
| 823 }).toList(); | |
| 824 } | |
| 825 | |
| 826 /// Like [createTypeAnnotation] except the dynamic type is converted to null. | |
| 827 static TypeAnnotation createOptionalType(DartType type) { | |
| 828 if (type.treatAsDynamic) { | |
| 829 return null; | |
| 830 } else { | |
| 831 return createType(type); | |
| 832 } | |
| 833 } | |
| 834 | |
| 835 /// Creates the [TypeAnnotation] for a [type] that is not function type. | |
| 836 static TypeAnnotation createType(DartType type) { | |
| 837 if (type is GenericType) { | |
| 838 if (type.treatAsRaw) { | |
| 839 return new TypeAnnotation(type.element.name)..dartType = type; | |
| 840 } | |
| 841 return new TypeAnnotation( | |
| 842 type.element.name, | |
| 843 type.typeArguments.map(createType).toList(growable:false)) | |
| 844 ..dartType = type; | |
| 845 } else if (type is VoidType) { | |
| 846 return new TypeAnnotation('void') | |
| 847 ..dartType = type; | |
| 848 } else if (type is TypeVariableType) { | |
| 849 return new TypeAnnotation(type.name) | |
| 850 ..dartType = type; | |
| 851 } else if (type is DynamicType) { | |
| 852 return new TypeAnnotation("dynamic") | |
| 853 ..dartType = type; | |
| 854 } else if (type is MalformedType) { | |
| 855 return new TypeAnnotation(type.name) | |
| 856 ..dartType = type; | |
| 857 } else { | |
| 858 throw "Unsupported type annotation: $type"; | |
| 859 } | |
| 860 } | |
| 861 | |
| 830 } | 862 } |
| 831 | 863 |
| 832 TypeAnnotation createTypeAnnotation(DartType type) { | |
| 833 if (type is GenericType) { | |
| 834 if (type.treatAsRaw) { | |
| 835 return new TypeAnnotation(type.element.name)..dartType = type; | |
| 836 } | |
| 837 return new TypeAnnotation( | |
| 838 type.element.name, | |
| 839 type.typeArguments.map(createTypeAnnotation).toList(growable:false)) | |
| 840 ..dartType = type; | |
| 841 } else if (type is VoidType) { | |
| 842 return new TypeAnnotation('void') | |
| 843 ..dartType = type; | |
| 844 } else if (type is TypeVariableType) { | |
| 845 return new TypeAnnotation(type.name) | |
| 846 ..dartType = type; | |
| 847 } else if (type is DynamicType) { | |
| 848 return new TypeAnnotation("dynamic") | |
| 849 ..dartType = type; | |
| 850 } else if (type is MalformedType) { | |
| 851 return new TypeAnnotation(type.name) | |
| 852 ..dartType = type; | |
| 853 } else { | |
| 854 throw "Unsupported type annotation: $type"; | |
| 855 } | |
| 856 } | |
| 857 | 864 |
| 858 class ConstantEmitter | 865 class ConstantEmitter |
| 859 extends ConstantExpressionVisitor<BuilderContext<Statement>, Expression> { | 866 extends ConstantExpressionVisitor<BuilderContext<Statement>, Expression> { |
| 860 const ConstantEmitter(); | 867 const ConstantEmitter(); |
| 861 | 868 |
| 869 /// Creates the [Expression] for the constant [exp]. | |
| 870 static Expression createExpression(ConstantExpression exp, | |
| 871 BuilderContext<Statement> context) { | |
| 872 return const ConstantEmitter().visit(exp, context); | |
| 873 } | |
| 874 | |
| 862 Expression handlePrimitiveConstant(PrimitiveConstantValue value) { | 875 Expression handlePrimitiveConstant(PrimitiveConstantValue value) { |
| 863 // Num constants may be negative, while literals must be non-negative: | 876 // Num constants may be negative, while literals must be non-negative: |
| 864 // Literals are non-negative in the specification, and a negated literal | 877 // Literals are non-negative in the specification, and a negated literal |
| 865 // parses as a call to unary `-`. The AST unparser assumes literals are | 878 // parses as a call to unary `-`. The AST unparser assumes literals are |
| 866 // non-negative and relies on this to avoid incorrectly generating `--`, | 879 // non-negative and relies on this to avoid incorrectly generating `--`, |
| 867 // the predecrement operator. | 880 // the predecrement operator. |
| 868 // Translate such constants into their positive value wrapped by | 881 // Translate such constants into their positive value wrapped by |
| 869 // the unary minus operator. | 882 // the unary minus operator. |
| 870 if (value.isNum) { | 883 if (value.isNum) { |
| 871 NumConstantValue numConstant = value; | 884 NumConstantValue numConstant = value; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 902 } | 915 } |
| 903 return new UnaryOperator('-', new Literal(positiveConstant)); | 916 return new UnaryOperator('-', new Literal(positiveConstant)); |
| 904 } | 917 } |
| 905 | 918 |
| 906 @override | 919 @override |
| 907 Expression visitList(ListConstantExpression exp, | 920 Expression visitList(ListConstantExpression exp, |
| 908 BuilderContext<Statement> context) { | 921 BuilderContext<Statement> context) { |
| 909 return new LiteralList( | 922 return new LiteralList( |
| 910 visitExpressions(exp.values, context), | 923 visitExpressions(exp.values, context), |
| 911 isConst: true, | 924 isConst: true, |
| 912 typeArgument: emitOptionalType(exp.type.typeArguments.single)); | 925 typeArgument: |
| 926 TypeGenerator.createOptionalType(exp.type.typeArguments.single)); | |
| 913 } | 927 } |
| 914 | 928 |
| 915 @override | 929 @override |
| 916 Expression visitMap(MapConstantExpression exp, | 930 Expression visitMap(MapConstantExpression exp, |
| 917 BuilderContext<Statement> context) { | 931 BuilderContext<Statement> context) { |
| 918 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( | 932 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( |
| 919 exp.values.length, | 933 exp.values.length, |
| 920 (i) => new LiteralMapEntry(visit(exp.keys[i], context), | 934 (i) => new LiteralMapEntry(visit(exp.keys[i], context), |
| 921 visit(exp.values[i], context))); | 935 visit(exp.values[i], context))); |
| 922 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw | 936 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw |
| 923 ? null | 937 ? null |
| 924 : exp.type.typeArguments.map(createTypeAnnotation).toList(); | 938 : exp.type.typeArguments.map(TypeGenerator.createType).toList(); |
| 925 return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); | 939 return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); |
| 926 } | 940 } |
| 927 | 941 |
| 928 @override | 942 @override |
| 929 Expression visitConstructed(ConstructedConstantExpresssion exp, | 943 Expression visitConstructed(ConstructedConstantExpresssion exp, |
| 930 BuilderContext<Statement> context) { | 944 BuilderContext<Statement> context) { |
| 931 int positionalArgumentCount = exp.selector.positionalArgumentCount; | 945 int positionalArgumentCount = exp.selector.positionalArgumentCount; |
| 932 List<Argument> args = new List<Argument>.generate( | 946 List<Argument> args = new List<Argument>.generate( |
| 933 positionalArgumentCount, | 947 positionalArgumentCount, |
| 934 (i) => visit(exp.arguments[i], context)); | 948 (i) => visit(exp.arguments[i], context)); |
| 935 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { | 949 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { |
| 936 args.add(new NamedArgument(exp.selector.namedArguments[i], | 950 args.add(new NamedArgument(exp.selector.namedArguments[i], |
| 937 visit(exp.arguments[positionalArgumentCount + i], context))); | 951 visit(exp.arguments[positionalArgumentCount + i], context))); |
| 938 } | 952 } |
| 939 | 953 |
| 940 FunctionElement constructor = exp.target; | 954 FunctionElement constructor = exp.target; |
| 941 String name = constructor.name.isEmpty ? null : constructor.name; | 955 String name = constructor.name.isEmpty ? null : constructor.name; |
| 942 return new CallNew(createTypeAnnotation(exp.type), | 956 return new CallNew(TypeGenerator.createType(exp.type), |
| 943 args, | 957 args, |
| 944 constructorName: name, | 958 constructorName: name, |
| 945 isConst: true) | 959 isConst: true) |
| 946 ..constructor = constructor | 960 ..constructor = constructor |
| 947 ..dartType = exp.type; | 961 ..dartType = exp.type; |
| 948 } | 962 } |
| 949 | 963 |
| 950 @override | 964 @override |
| 951 Expression visitConcatenate(ConcatenateConstantExpression exp, | 965 Expression visitConcatenate(ConcatenateConstantExpression exp, |
| 952 BuilderContext<Statement> context) { | 966 BuilderContext<Statement> context) { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1078 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); | 1092 : super(name, ElementKind.VARIABLE, enclosingElement, variables, null); |
| 1079 | 1093 |
| 1080 ExecutableElement get executableContext => enclosingElement; | 1094 ExecutableElement get executableContext => enclosingElement; |
| 1081 | 1095 |
| 1082 ExecutableElement get memberContext => executableContext.memberContext; | 1096 ExecutableElement get memberContext => executableContext.memberContext; |
| 1083 | 1097 |
| 1084 bool get isLocal => true; | 1098 bool get isLocal => true; |
| 1085 | 1099 |
| 1086 LibraryElement get implementationLibrary => enclosingElement.library; | 1100 LibraryElement get implementationLibrary => enclosingElement.library; |
| 1087 } | 1101 } |
| OLD | NEW |