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 import '../common.dart'; | 5 import '../common.dart'; |
6 import '../common/backend_api.dart' show ForeignResolver; | 6 import '../common/backend_api.dart' show ForeignResolver; |
7 import '../common/resolution.dart' show Parsing, Resolution; | 7 import '../common/resolution.dart' show ParsingContext, Resolution; |
8 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
9 import '../constants/values.dart'; | 9 import '../constants/values.dart'; |
10 import '../core_types.dart' show CoreTypes; | 10 import '../core_types.dart' show CoreTypes; |
11 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
13 import '../js/js.dart' as js; | 13 import '../js/js.dart' as js; |
14 import '../js_backend/js_backend.dart'; | 14 import '../js_backend/js_backend.dart'; |
15 import '../tree/tree.dart'; | 15 import '../tree/tree.dart'; |
16 import '../universe/side_effects.dart' show SideEffects; | 16 import '../universe/side_effects.dart' show SideEffects; |
17 import '../util/util.dart'; | 17 import '../util/util.dart'; |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 default: | 453 default: |
454 reportError("Unrecognized side-effect flag: '$dependency'."); | 454 reportError("Unrecognized side-effect flag: '$dependency'."); |
455 } | 455 } |
456 } | 456 } |
457 } | 457 } |
458 | 458 |
459 return sideEffects; | 459 return sideEffects; |
460 } | 460 } |
461 | 461 |
462 static NativeBehavior ofJsCall(Send jsCall, DiagnosticReporter reporter, | 462 static NativeBehavior ofJsCall(Send jsCall, DiagnosticReporter reporter, |
463 Parsing parsing, CoreTypes coreTypes, ForeignResolver resolver) { | 463 ParsingContext parsing, CoreTypes coreTypes, ForeignResolver resolver) { |
464 // The first argument of a JS-call is a string encoding various attributes | 464 // The first argument of a JS-call is a string encoding various attributes |
465 // of the code. | 465 // of the code. |
466 // | 466 // |
467 // 'Type1|Type2'. A union type. | 467 // 'Type1|Type2'. A union type. |
468 // '=Object'. A JavaScript Object, no subtype. | 468 // '=Object'. A JavaScript Object, no subtype. |
469 | 469 |
470 NativeBehavior behavior = new NativeBehavior(); | 470 NativeBehavior behavior = new NativeBehavior(); |
471 | 471 |
472 var argNodes = jsCall.arguments; | 472 var argNodes = jsCall.arguments; |
473 if (argNodes.isEmpty || argNodes.tail.isEmpty) { | 473 if (argNodes.isEmpty || argNodes.tail.isEmpty) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 new ThrowBehaviorVisitor().analyze(behavior.codeTemplate.ast); | 544 new ThrowBehaviorVisitor().analyze(behavior.codeTemplate.ast); |
545 } | 545 } |
546 | 546 |
547 return behavior; | 547 return behavior; |
548 } | 548 } |
549 | 549 |
550 static void _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( | 550 static void _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
551 NativeBehavior behavior, | 551 NativeBehavior behavior, |
552 Send jsBuiltinOrEmbeddedGlobalCall, | 552 Send jsBuiltinOrEmbeddedGlobalCall, |
553 DiagnosticReporter reporter, | 553 DiagnosticReporter reporter, |
554 Parsing parsing, | 554 ParsingContext parsing, |
555 CoreTypes coreTypes, | 555 CoreTypes coreTypes, |
556 ForeignResolver resolver, | 556 ForeignResolver resolver, |
557 {bool isBuiltin, | 557 {bool isBuiltin, |
558 List<String> validTags}) { | 558 List<String> validTags}) { |
559 // The first argument of a JS-embedded global call is a string encoding | 559 // The first argument of a JS-embedded global call is a string encoding |
560 // the type of the code. | 560 // the type of the code. |
561 // | 561 // |
562 // 'Type1|Type2'. A union type. | 562 // 'Type1|Type2'. A union type. |
563 // '=Object'. A JavaScript Object, no subtype. | 563 // '=Object'. A JavaScript Object, no subtype. |
564 | 564 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 setSideEffects: setSideEffects, | 612 setSideEffects: setSideEffects, |
613 typesReturned: behavior.typesReturned, | 613 typesReturned: behavior.typesReturned, |
614 typesInstantiated: behavior.typesInstantiated, | 614 typesInstantiated: behavior.typesInstantiated, |
615 objectType: coreTypes.objectType, | 615 objectType: coreTypes.objectType, |
616 nullType: coreTypes.nullType); | 616 nullType: coreTypes.nullType); |
617 } | 617 } |
618 | 618 |
619 static NativeBehavior ofJsBuiltinCall( | 619 static NativeBehavior ofJsBuiltinCall( |
620 Send jsBuiltinCall, | 620 Send jsBuiltinCall, |
621 DiagnosticReporter reporter, | 621 DiagnosticReporter reporter, |
622 Parsing parsing, | 622 ParsingContext parsing, |
623 CoreTypes coreTypes, | 623 CoreTypes coreTypes, |
624 ForeignResolver resolver) { | 624 ForeignResolver resolver) { |
625 NativeBehavior behavior = new NativeBehavior(); | 625 NativeBehavior behavior = new NativeBehavior(); |
626 behavior.sideEffects.setTo(new SideEffects()); | 626 behavior.sideEffects.setTo(new SideEffects()); |
627 | 627 |
628 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( | 628 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
629 behavior, jsBuiltinCall, reporter, parsing, coreTypes, resolver, | 629 behavior, jsBuiltinCall, reporter, parsing, coreTypes, resolver, |
630 isBuiltin: true); | 630 isBuiltin: true); |
631 | 631 |
632 return behavior; | 632 return behavior; |
633 } | 633 } |
634 | 634 |
635 static NativeBehavior ofJsEmbeddedGlobalCall( | 635 static NativeBehavior ofJsEmbeddedGlobalCall( |
636 Send jsEmbeddedGlobalCall, | 636 Send jsEmbeddedGlobalCall, |
637 DiagnosticReporter reporter, | 637 DiagnosticReporter reporter, |
638 Parsing parsing, | 638 ParsingContext parsing, |
639 CoreTypes coreTypes, | 639 CoreTypes coreTypes, |
640 ForeignResolver resolver) { | 640 ForeignResolver resolver) { |
641 NativeBehavior behavior = new NativeBehavior(); | 641 NativeBehavior behavior = new NativeBehavior(); |
642 // TODO(sra): Allow the use site to override these defaults. | 642 // TODO(sra): Allow the use site to override these defaults. |
643 // Embedded globals are usually pre-computed data structures or JavaScript | 643 // Embedded globals are usually pre-computed data structures or JavaScript |
644 // functions that never change. | 644 // functions that never change. |
645 behavior.sideEffects.setTo(new SideEffects.empty()); | 645 behavior.sideEffects.setTo(new SideEffects.empty()); |
646 behavior.throwBehavior = NativeThrowBehavior.NEVER; | 646 behavior.throwBehavior = NativeThrowBehavior.NEVER; |
647 | 647 |
648 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( | 648 _fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 | 766 |
767 Iterable<ConstantValue> fields = constructedObject.fields.values; | 767 Iterable<ConstantValue> fields = constructedObject.fields.values; |
768 // TODO(sra): Better validation of the constant. | 768 // TODO(sra): Better validation of the constant. |
769 if (fields.length != 1 || !fields.single.isString) { | 769 if (fields.length != 1 || !fields.single.isString) { |
770 reporter.internalError( | 770 reporter.internalError( |
771 annotation, 'Annotations needs one string: ${annotation.node}'); | 771 annotation, 'Annotations needs one string: ${annotation.node}'); |
772 } | 772 } |
773 StringConstantValue specStringConstant = fields.single; | 773 StringConstantValue specStringConstant = fields.single; |
774 String specString = specStringConstant.toDartString().slowToString(); | 774 String specString = specStringConstant.toDartString().slowToString(); |
775 for (final typeString in specString.split('|')) { | 775 for (final typeString in specString.split('|')) { |
776 var type = _parseType(typeString, compiler.parsing, lookup, annotation); | 776 var type = |
| 777 _parseType(typeString, compiler.parsingContext, lookup, annotation); |
777 if (types == null) types = []; | 778 if (types == null) types = []; |
778 types.add(type); | 779 types.add(type); |
779 } | 780 } |
780 } | 781 } |
781 return types; | 782 return types; |
782 } | 783 } |
783 | 784 |
784 /// Models the behavior of having intances of [type] escape from Dart code | 785 /// Models the behavior of having intances of [type] escape from Dart code |
785 /// into native code. | 786 /// into native code. |
786 void _escape(DartType type, Resolution resolution) { | 787 void _escape(DartType type, Resolution resolution) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
840 } else { | 841 } else { |
841 // Otherwise, when the declared type is a Dart type, we do not | 842 // Otherwise, when the declared type is a Dart type, we do not |
842 // register an allocation because we assume it cannot be instantiated | 843 // register an allocation because we assume it cannot be instantiated |
843 // from within the JS-interop code. It must have escaped from another | 844 // from within the JS-interop code. It must have escaped from another |
844 // API. | 845 // API. |
845 } | 846 } |
846 } | 847 } |
847 } | 848 } |
848 } | 849 } |
849 | 850 |
850 static dynamic _parseType( | 851 static dynamic _parseType(String typeString, ParsingContext parsing, |
851 String typeString, Parsing parsing, lookup(name), locationNodeOrElement) { | 852 lookup(name), locationNodeOrElement) { |
852 DiagnosticReporter reporter = parsing.reporter; | 853 DiagnosticReporter reporter = parsing.reporter; |
853 if (typeString == '=Object') return SpecialType.JsObject; | 854 if (typeString == '=Object') return SpecialType.JsObject; |
854 if (typeString == 'dynamic') { | 855 if (typeString == 'dynamic') { |
855 return const DynamicType(); | 856 return const DynamicType(); |
856 } | 857 } |
857 var type = lookup(typeString); | 858 var type = lookup(typeString); |
858 if (type != null) return type; | 859 if (type != null) return type; |
859 | 860 |
860 int index = typeString.indexOf('<'); | 861 int index = typeString.indexOf('<'); |
861 if (index < 1) { | 862 if (index < 1) { |
862 reporter.reportErrorMessage(_errorNode(locationNodeOrElement, parsing), | 863 reporter.reportErrorMessage(_errorNode(locationNodeOrElement, parsing), |
863 MessageKind.GENERIC, {'text': "Type '$typeString' not found."}); | 864 MessageKind.GENERIC, {'text': "Type '$typeString' not found."}); |
864 return const DynamicType(); | 865 return const DynamicType(); |
865 } | 866 } |
866 type = lookup(typeString.substring(0, index)); | 867 type = lookup(typeString.substring(0, index)); |
867 if (type != null) { | 868 if (type != null) { |
868 // TODO(sra): Parse type parameters. | 869 // TODO(sra): Parse type parameters. |
869 return type; | 870 return type; |
870 } | 871 } |
871 reporter.reportErrorMessage(_errorNode(locationNodeOrElement, parsing), | 872 reporter.reportErrorMessage(_errorNode(locationNodeOrElement, parsing), |
872 MessageKind.GENERIC, {'text': "Type '$typeString' not found."}); | 873 MessageKind.GENERIC, {'text': "Type '$typeString' not found."}); |
873 return const DynamicType(); | 874 return const DynamicType(); |
874 } | 875 } |
875 | 876 |
876 static _errorNode(locationNodeOrElement, Parsing parsing) { | 877 static _errorNode(locationNodeOrElement, ParsingContext parsing) { |
877 if (locationNodeOrElement is Node) return locationNodeOrElement; | 878 if (locationNodeOrElement is Node) return locationNodeOrElement; |
878 return locationNodeOrElement.parseNode(parsing); | 879 return locationNodeOrElement.parseNode(parsing); |
879 } | 880 } |
880 } | 881 } |
OLD | NEW |