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 |