| 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 ParsingContext, 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; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 /// This class is a temporary work-around until we get a more powerful DartType. | 22 /// This class is a temporary work-around until we get a more powerful DartType. |
| 23 class SpecialType { | 23 class SpecialType { |
| 24 final String name; | 24 final String name; |
| 25 const SpecialType._(this.name); | 25 const SpecialType._(this.name); |
| 26 | 26 |
| 27 /// The type Object, but no subtypes: | 27 /// The type Object, but no subtypes: |
| 28 static const JsObject = const SpecialType._('=Object'); | 28 static const JsObject = const SpecialType._('=Object'); |
| 29 | 29 |
| 30 int get hashCode => name.hashCode; | 30 int get hashCode => name.hashCode; |
| 31 |
| 32 static SpecialType fromName(String name) { |
| 33 if (name == '=Object') { |
| 34 return JsObject; |
| 35 } else { |
| 36 throw new UnsupportedError("Unknown SpecialType '$name'."); |
| 37 } |
| 38 } |
| 31 } | 39 } |
| 32 | 40 |
| 33 /// Description of the exception behaviour of native code. | 41 /// Description of the exception behaviour of native code. |
| 34 /// | 42 /// |
| 35 /// TODO(sra): Replace with something that better supports specialization on | 43 /// TODO(sra): Replace with something that better supports specialization on |
| 36 /// first argument properties. | 44 /// first argument properties. |
| 37 class NativeThrowBehavior { | 45 class NativeThrowBehavior { |
| 38 static const NativeThrowBehavior NEVER = const NativeThrowBehavior._(0); | 46 static const NativeThrowBehavior NEVER = const NativeThrowBehavior._(0); |
| 39 static const NativeThrowBehavior MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS = | 47 static const NativeThrowBehavior MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS = |
| 40 const NativeThrowBehavior._(1); | 48 const NativeThrowBehavior._(1); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 63 return this; | 71 return this; |
| 64 } | 72 } |
| 65 | 73 |
| 66 String toString() { | 74 String toString() { |
| 67 if (this == NEVER) return 'never'; | 75 if (this == NEVER) return 'never'; |
| 68 if (this == MAY) return 'may'; | 76 if (this == MAY) return 'may'; |
| 69 if (this == MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS) return 'null(1)'; | 77 if (this == MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS) return 'null(1)'; |
| 70 if (this == MUST) return 'must'; | 78 if (this == MUST) return 'must'; |
| 71 return 'NativeThrowBehavior($_bits)'; | 79 return 'NativeThrowBehavior($_bits)'; |
| 72 } | 80 } |
| 81 |
| 82 /// Canonical list of marker values. |
| 83 /// |
| 84 /// Added to make [NativeThrowBehavior] enum-like. |
| 85 static const List<NativeThrowBehavior> values = const <NativeThrowBehavior>[ |
| 86 NEVER, |
| 87 MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS, |
| 88 MAY, |
| 89 MUST, |
| 90 ]; |
| 91 |
| 92 /// Index to this marker within [values]. |
| 93 /// |
| 94 /// Added to make [NativeThrowBehavior] enum-like. |
| 95 int get index => values.indexOf(this); |
| 73 } | 96 } |
| 74 | 97 |
| 75 /** | 98 /** |
| 76 * A summary of the behavior of a native element. | 99 * A summary of the behavior of a native element. |
| 77 * | 100 * |
| 78 * Native code can return values of one type and cause native subtypes of | 101 * Native code can return values of one type and cause native subtypes of |
| 79 * another type to be instantiated. By default, we compute both from the | 102 * another type to be instantiated. By default, we compute both from the |
| 80 * declared type. | 103 * declared type. |
| 81 * | 104 * |
| 82 * A field might yield any native type that 'is' the field type. | 105 * A field might yield any native type that 'is' the field type. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 102 * Types in annotations are non-nullable, so include `@Returns('Null')` if | 125 * Types in annotations are non-nullable, so include `@Returns('Null')` if |
| 103 * `null` may be returned. | 126 * `null` may be returned. |
| 104 */ | 127 */ |
| 105 class NativeBehavior { | 128 class NativeBehavior { |
| 106 /// [DartType]s or [SpecialType]s returned or yielded by the native element. | 129 /// [DartType]s or [SpecialType]s returned or yielded by the native element. |
| 107 final List typesReturned = []; | 130 final List typesReturned = []; |
| 108 | 131 |
| 109 /// [DartType]s or [SpecialType]s instantiated by the native element. | 132 /// [DartType]s or [SpecialType]s instantiated by the native element. |
| 110 final List typesInstantiated = []; | 133 final List typesInstantiated = []; |
| 111 | 134 |
| 135 String codeTemplateText; |
| 112 // If this behavior is for a JS expression, [codeTemplate] contains the | 136 // If this behavior is for a JS expression, [codeTemplate] contains the |
| 113 // parsed tree. | 137 // parsed tree. |
| 114 js.Template codeTemplate; | 138 js.Template codeTemplate; |
| 115 | 139 |
| 116 final SideEffects sideEffects = new SideEffects.empty(); | 140 final SideEffects sideEffects; |
| 117 | 141 |
| 118 NativeThrowBehavior throwBehavior = NativeThrowBehavior.MAY; | 142 NativeThrowBehavior throwBehavior = NativeThrowBehavior.MAY; |
| 119 | 143 |
| 120 bool isAllocation = false; | 144 bool isAllocation = false; |
| 121 bool useGvn = false; | 145 bool useGvn = false; |
| 122 | 146 |
| 123 // TODO(sra): Make NativeBehavior immutable so PURE and PURE_ALLOCATION can be | 147 // TODO(sra): Make NativeBehavior immutable so PURE and PURE_ALLOCATION can be |
| 124 // final constant-like objects. | 148 // final constant-like objects. |
| 125 static NativeBehavior get PURE => NativeBehavior._makePure(); | 149 static NativeBehavior get PURE => NativeBehavior._makePure(); |
| 126 static NativeBehavior get PURE_ALLOCATION => | 150 static NativeBehavior get PURE_ALLOCATION => |
| 127 NativeBehavior._makePure(isAllocation: true); | 151 NativeBehavior._makePure(isAllocation: true); |
| 128 static NativeBehavior get CHANGES_OTHER => NativeBehavior._makeChangesOther(); | 152 static NativeBehavior get CHANGES_OTHER => NativeBehavior._makeChangesOther(); |
| 129 static NativeBehavior get DEPENDS_OTHER => NativeBehavior._makeDependsOther(); | 153 static NativeBehavior get DEPENDS_OTHER => NativeBehavior._makeDependsOther(); |
| 130 | 154 |
| 155 NativeBehavior() : sideEffects = new SideEffects.empty(); |
| 156 |
| 157 NativeBehavior.internal(this.sideEffects); |
| 158 |
| 131 String toString() { | 159 String toString() { |
| 132 return 'NativeBehavior(' | 160 return 'NativeBehavior(' |
| 133 'returns: ${typesReturned}' | 161 'returns: ${typesReturned}' |
| 134 ', creates: ${typesInstantiated}' | 162 ', creates: ${typesInstantiated}' |
| 135 ', sideEffects: ${sideEffects}' | 163 ', sideEffects: ${sideEffects}' |
| 136 ', throws: ${throwBehavior}' | 164 ', throws: ${throwBehavior}' |
| 137 '${isAllocation ? ", isAllocation" : ""}' | 165 '${isAllocation ? ", isAllocation" : ""}' |
| 138 '${useGvn ? ", useGvn" : ""}' | 166 '${useGvn ? ", useGvn" : ""}' |
| 139 ')'; | 167 ')'; |
| 140 } | 168 } |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 return behavior; | 511 return behavior; |
| 484 } | 512 } |
| 485 | 513 |
| 486 var codeArgument = argNodes.tail.head; | 514 var codeArgument = argNodes.tail.head; |
| 487 if (codeArgument is! StringNode || codeArgument.isInterpolation) { | 515 if (codeArgument is! StringNode || codeArgument.isInterpolation) { |
| 488 reporter.reportErrorMessage(codeArgument, MessageKind.GENERIC, | 516 reporter.reportErrorMessage(codeArgument, MessageKind.GENERIC, |
| 489 {'text': "JS second argument must be a string literal."}); | 517 {'text': "JS second argument must be a string literal."}); |
| 490 return behavior; | 518 return behavior; |
| 491 } | 519 } |
| 492 | 520 |
| 493 behavior.codeTemplate = | 521 behavior.codeTemplateText = codeArgument.dartString.slowToString(); |
| 494 js.js.parseForeignJS(codeArgument.dartString.slowToString()); | 522 behavior.codeTemplate = js.js.parseForeignJS(behavior.codeTemplateText); |
| 495 | 523 |
| 496 String specString = specArgument.dartString.slowToString(); | 524 String specString = specArgument.dartString.slowToString(); |
| 497 | 525 |
| 498 dynamic resolveType(String typeString) { | 526 dynamic resolveType(String typeString) { |
| 499 return _parseType( | 527 return _parseType( |
| 500 typeString, | 528 typeString, |
| 501 parsing, | 529 parsing, |
| 502 (name) => resolver.resolveTypeFromString(specArgument, name), | 530 (name) => resolver.resolveTypeFromString(specArgument, name), |
| 503 specArgument); | 531 specArgument); |
| 504 } | 532 } |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 reporter.reportErrorMessage(_errorNode(locationNodeOrElement, parsing), | 900 reporter.reportErrorMessage(_errorNode(locationNodeOrElement, parsing), |
| 873 MessageKind.GENERIC, {'text': "Type '$typeString' not found."}); | 901 MessageKind.GENERIC, {'text': "Type '$typeString' not found."}); |
| 874 return const DynamicType(); | 902 return const DynamicType(); |
| 875 } | 903 } |
| 876 | 904 |
| 877 static _errorNode(locationNodeOrElement, ParsingContext parsing) { | 905 static _errorNode(locationNodeOrElement, ParsingContext parsing) { |
| 878 if (locationNodeOrElement is Node) return locationNodeOrElement; | 906 if (locationNodeOrElement is Node) return locationNodeOrElement; |
| 879 return locationNodeOrElement.parseNode(parsing); | 907 return locationNodeOrElement.parseNode(parsing); |
| 880 } | 908 } |
| 881 } | 909 } |
| OLD | NEW |