OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** | 5 /** |
6 * Represents a meta-value for code generation. | 6 * Represents a meta-value for code generation. |
7 */ | 7 */ |
8 class Value { | 8 class Value { |
9 /** The [Type] of the [Value]. */ | 9 /** The [Type] of the [Value]. */ |
10 Type type; | 10 Type type; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 fromType = world.objectType; | 188 fromType = world.objectType; |
189 } | 189 } |
190 bool bothNum = type.isNum && toType.isNum; | 190 bool bothNum = type.isNum && toType.isNum; |
191 return fromType.isSubtypeOf(toType) || bothNum; | 191 return fromType.isSubtypeOf(toType) || bothNum; |
192 } | 192 } |
193 return false; | 193 return false; |
194 } | 194 } |
195 | 195 |
196 /** | 196 /** |
197 * Assign or convert this value to another type. | 197 * Assign or convert this value to another type. |
198 * This is used for converting between function types, and inserting type | 198 * This is used for converting between function types, inserting type |
199 * checks when --enable_type_checks is enabled. | 199 * checks when --enable_type_checks is enabled, and wrapping callback |
200 * functions passed to the dom so we can restore their isolate context. | |
200 */ | 201 */ |
201 // WARNING: this needs to be kept in sync with needsConversion above. | 202 // WARNING: this needs to be kept in sync with needsConversion above. |
202 Value convertTo(MethodGenerator context, Type toType, Node node, | 203 Value convertTo(MethodGenerator context, Type toType, Node node, |
203 [bool isDynamic=false]) { | 204 [bool isDynamic=false]) { |
204 | 205 |
205 // Issue type warnings unless we are processing a dynamic operation. | 206 // Issue type warnings unless we are processing a dynamic operation. |
206 bool checked = !isDynamic; | 207 bool checked = !isDynamic; |
207 | 208 |
208 var callMethod = toType.getCallMethod(); | 209 var callMethod = toType.getCallMethod(); |
209 if (callMethod != null) { | 210 if (callMethod != null) { |
210 if (checked && !toType.isAssignable(type)) { | 211 if (checked && !toType.isAssignable(type)) { |
211 convertWarning(toType, node); | 212 convertWarning(toType, node); |
212 } | 213 } |
213 | 214 |
214 int arity = callMethod.parameters.length; | 215 int arity = callMethod.parameters.length; |
215 var myCall = type.getCallMethod(); | 216 var myCall = type.getCallMethod(); |
216 if (myCall == null || myCall.parameters.length != arity) { | 217 if (myCall == null || myCall.parameters.length != arity) { |
217 final stub = world.functionType.getCallStub(new Arguments.bare(arity)); | 218 final stub = world.functionType.getCallStub(new Arguments.bare(arity)); |
218 return new Value(toType, 'to\$${stub.name}($code)'); | 219 var val = new Value(toType, 'to\$${stub.name}($code)'); |
220 return _isDomCallback(toType) && !_isDomCallback(type) ? | |
Siggi Cherem (dart-lang)
2011/11/08 02:06:26
BTW, this was a cool trick that John came up with.
Jennifer Messerly
2011/11/08 05:04:35
It'd be worth putting the "we have to first recons
jimhug
2011/11/08 15:39:01
I'm not sure about the right long-term solution, b
Siggi Cherem (dart-lang)
2011/11/08 17:56:42
Done
| |
221 val._wrapDomCallback(toType, arity) : val; | |
222 } else if (_isDomCallback(toType) && !_isDomCallback(type)) { | |
223 return _wrapDomCallback(toType, arity); | |
219 } | 224 } |
220 } | 225 } |
221 | 226 |
222 // Don't add runtime asserts unless we have type checks turned on. | 227 // Don't add runtime asserts unless we have type checks turned on. |
223 if (!options.enableTypeChecks) { | 228 if (!options.enableTypeChecks) { |
224 return this; | 229 return this; |
225 } | 230 } |
226 | 231 |
227 // If we're assigning from a var, pretend it's Object for the purpose of | 232 // If we're assigning from a var, pretend it's Object for the purpose of |
228 // runtime checks. | 233 // runtime checks. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 } else { | 271 } else { |
267 // TODO(jmesserly): this is hacky. | 272 // TODO(jmesserly): this is hacky. |
268 if (code.startsWith('\$notnull_bool')) { | 273 if (code.startsWith('\$notnull_bool')) { |
269 return this; | 274 return this; |
270 } else { | 275 } else { |
271 return new Value(world.boolType, '\$notnull_bool($code)'); | 276 return new Value(world.boolType, '\$notnull_bool($code)'); |
272 } | 277 } |
273 } | 278 } |
274 } | 279 } |
275 | 280 |
281 bool _isDomCallback(toType) { | |
jimhug
2011/11/08 15:39:01
This could use a doc comment and possibly a TODO a
Siggi Cherem (dart-lang)
2011/11/08 17:56:42
Done.
| |
282 return (toType.definition is FunctionTypeDefinition | |
283 && toType.library == world.dom); | |
284 } | |
285 | |
286 Value _wrapDomCallback(Type toType, int arity) { | |
287 return new Value(toType, '\$wrap_call\$$arity($code)'); | |
288 } | |
289 | |
276 /** | 290 /** |
277 * Generates a run time type assertion for the given value. This works like | 291 * Generates a run time type assertion for the given value. This works like |
278 * [instanceOf], but it allows null since Dart types are nullable. | 292 * [instanceOf], but it allows null since Dart types are nullable. |
279 * Also it will throw a TypeError if it gets the wrong type. | 293 * Also it will throw a TypeError if it gets the wrong type. |
280 */ | 294 */ |
281 Value _typeAssert(MethodGenerator context, Type toType, Node node) { | 295 Value _typeAssert(MethodGenerator context, Type toType, Node node) { |
282 if (toType is ParameterType) { | 296 if (toType is ParameterType) { |
283 ParameterType p = toType; | 297 ParameterType p = toType; |
284 toType = p.extendsType; | 298 toType = p.extendsType; |
285 } | 299 } |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
598 return 1; | 612 return 1; |
599 } else if (name != null && other.name == null) { | 613 } else if (name != null && other.name == null) { |
600 return -1; | 614 return -1; |
601 } else if (name != null) { | 615 } else if (name != null) { |
602 return name.compareTo(other.name); | 616 return name.compareTo(other.name); |
603 } else { | 617 } else { |
604 return field.name.compareTo(other.field.name); | 618 return field.name.compareTo(other.field.name); |
605 } | 619 } |
606 } | 620 } |
607 } | 621 } |
OLD | NEW |