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 part of native; | 5 part of native; |
6 | 6 |
7 /// This class is a temporary work-around until we get a more powerful DartType. | 7 /// This class is a temporary work-around until we get a more powerful DartType. |
8 class SpecialType { | 8 class SpecialType { |
9 final String name; | 9 final String name; |
10 const SpecialType._(this.name); | 10 const SpecialType._(this.name); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 } | 133 } |
134 | 134 |
135 /// Processes the type specification string of a call to JS and stores the | 135 /// Processes the type specification string of a call to JS and stores the |
136 /// result in the [typesReturned] and [typesInstantiated]. It furthermore | 136 /// result in the [typesReturned] and [typesInstantiated]. It furthermore |
137 /// computes the side effects, and, if given, invokes [setSideEffects] with | 137 /// computes the side effects, and, if given, invokes [setSideEffects] with |
138 /// the computed effects. If no side effects are encoded in the [specString] | 138 /// the computed effects. If no side effects are encoded in the [specString] |
139 /// the [setSideEffects] method is not invoked. | 139 /// the [setSideEffects] method is not invoked. |
140 /// | 140 /// |
141 /// Two forms of the string is supported: | 141 /// Two forms of the string is supported: |
142 /// | 142 /// |
143 /// 1) A single type string of the form 'void', '', 'var' or 'T1|...|Tn' | 143 /// 1) A single type string of the form 'void', '', 'var' or 'T1|...|Tn' which |
144 /// which defines the types returned and for the later form also created by | 144 /// defines the types returned, and, for the last form, the types also |
145 /// the call to JS. | 145 /// created by the call to JS. 'var' (and '') are like 'dynamic' or |
| 146 /// 'Object' except that 'dynamic' would indicate that objects of any type |
| 147 /// are created, which defeats tree-shaking. Think of 'var' (and '') as |
| 148 /// meaning 'any pre-existing type'. |
| 149 /// |
| 150 /// The types Ti are non-nullable, so add class `Null` to specify a |
| 151 /// nullable type, e.g `'String|Null'`. |
146 /// | 152 /// |
147 /// 2) A sequence of <tag>:<value> pairs of the following kinds | 153 /// 2) A sequence of <tag>:<value> pairs of the following kinds |
148 /// | 154 /// |
149 /// <type-tag>:<type-string> | 155 /// <type-tag>:<type-string> |
150 /// <effect-tag>:<effect-string> | 156 /// <effect-tag>:<effect-string> |
151 /// throws:<throws-string> | 157 /// throws:<throws-string> |
152 /// gvn:<gvn-string> | 158 /// gvn:<gvn-string> |
153 /// new:<new-string> | 159 /// new:<new-string> |
154 /// | 160 /// |
155 /// A <type-tag> is either 'returns' or 'creates' and <type-string> is a | 161 /// A <type-tag> is either 'returns' or 'creates' and <type-string> is a |
156 /// type string like in 1). The type string marked by 'returns' defines the | 162 /// type string like in 1). The type string marked by 'returns' defines the |
157 /// types returned and 'creates' defines the types created by the call to | 163 /// types returned and 'creates' defines the types created by the call to |
158 /// JS. | 164 /// JS. If 'creates' is missing, it defaults to 'returns'. |
159 /// | 165 /// |
160 /// An <effect-tag> is either 'effects' or 'depends' and <effect-string> is | 166 /// An <effect-tag> is either 'effects' or 'depends' and <effect-string> is |
161 /// either 'all', 'none' or a comma-separated list of 'no-index', | 167 /// either 'all', 'none' or a comma-separated list of 'no-index', |
162 /// 'no-instance', 'no-static'. | 168 /// 'no-instance', 'no-static'. |
163 /// | 169 /// |
164 /// The flag 'all' indicates that the call affects/depends on every | 170 /// The flag 'all' indicates that the call affects/depends on every |
165 /// side-effect. The flag 'none' indicates that the call does not affect | 171 /// side-effect. The flag 'none' indicates that the call does not affect |
166 /// (resp. depends on) anything. | 172 /// (resp. depends on) anything. |
167 /// | 173 /// |
168 /// 'no-index' indicates that the call does *not* do any array index-store | 174 /// 'no-index' indicates that the call does *not* do any array index-store |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 if (tagString == null) return null; | 308 if (tagString == null) return null; |
303 var value = map[tagString]; | 309 var value = map[tagString]; |
304 if (value == null) { | 310 if (value == null) { |
305 reportError("Unknown '$tag' specification: '$tagString'."); | 311 reportError("Unknown '$tag' specification: '$tagString'."); |
306 } | 312 } |
307 return value; | 313 return value; |
308 } | 314 } |
309 | 315 |
310 String returns = values['returns']; | 316 String returns = values['returns']; |
311 if (returns != null) { | 317 if (returns != null) { |
312 resolveTypesString(returns, onVar: () { | 318 resolveTypesString(returns, |
313 typesReturned.add(objectType); | 319 onVar: () { |
314 typesReturned.add(nullType); | 320 typesReturned.add(objectType); |
315 }, onType: (type) { | 321 typesReturned.add(nullType); |
316 typesReturned.add(type); | 322 }, |
317 }); | 323 onType: (type) { |
| 324 typesReturned.add(type); |
| 325 }); |
318 } | 326 } |
319 | 327 |
320 String creates = values['creates']; | 328 String creates = values['creates']; |
321 if (creates != null) { | 329 if (creates != null) { |
322 resolveTypesString(creates, onVoid: () { | 330 resolveTypesString(creates, |
323 reportError("Invalid type string 'creates:$creates'"); | 331 onVoid: () { |
324 }, onVar: () { | 332 reportError("Invalid type string 'creates:$creates'"); |
325 reportError("Invalid type string 'creates:$creates'"); | 333 }, |
326 }, onType: (type) { | 334 onType: (type) { |
327 typesInstantiated.add(type); | 335 typesInstantiated.add(type); |
328 }); | 336 }); |
| 337 } else if (returns != null) { |
| 338 resolveTypesString(returns, |
| 339 onType: (type) { |
| 340 typesInstantiated.add(type); |
| 341 }); |
329 } | 342 } |
330 | 343 |
331 const throwsOption = const <String, NativeThrowBehavior>{ | 344 const throwsOption = const <String, NativeThrowBehavior>{ |
332 'never': NativeThrowBehavior.NEVER, | 345 'never': NativeThrowBehavior.NEVER, |
333 'null(1)': NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS, | 346 'null(1)': NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS, |
334 'may': NativeThrowBehavior.MAY, | 347 'may': NativeThrowBehavior.MAY, |
335 'must': NativeThrowBehavior.MUST }; | 348 'must': NativeThrowBehavior.MUST }; |
336 | 349 |
337 const boolOptions = const<String, bool>{'true': true, 'false': false}; | 350 const boolOptions = const<String, bool>{'true': true, 'false': false}; |
338 | 351 |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 MessageKind.GENERIC, | 875 MessageKind.GENERIC, |
863 {'text': "Type '$typeString' not found."}); | 876 {'text': "Type '$typeString' not found."}); |
864 return const DynamicType(); | 877 return const DynamicType(); |
865 } | 878 } |
866 | 879 |
867 static _errorNode(locationNodeOrElement, Parsing parsing) { | 880 static _errorNode(locationNodeOrElement, Parsing parsing) { |
868 if (locationNodeOrElement is Node) return locationNodeOrElement; | 881 if (locationNodeOrElement is Node) return locationNodeOrElement; |
869 return locationNodeOrElement.parseNode(parsing); | 882 return locationNodeOrElement.parseNode(parsing); |
870 } | 883 } |
871 } | 884 } |
OLD | NEW |