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