Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 * This part contains helpers for supporting runtime type information. | 6 * This part contains helpers for supporting runtime type information. |
| 7 * | 7 * |
| 8 * The helper use a mixture of Dart and JavaScript objects. To indicate which is | 8 * The helper use a mixture of Dart and JavaScript objects. To indicate which is |
| 9 * used where we adopt the scheme of using explicit type annotation for Dart | 9 * used where we adopt the scheme of using explicit type annotation for Dart |
| 10 * objects and 'var' or omitted return type for JavaScript objects. | 10 * objects and 'var' or omitted return type for JavaScript objects. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 getRuntimeTypeInfo(Object target) { | 99 getRuntimeTypeInfo(Object target) { |
| 100 if (target == null) return null; | 100 if (target == null) return null; |
| 101 return JS('var', r'#.$builtinTypeInfo', target); | 101 return JS('var', r'#.$builtinTypeInfo', target); |
| 102 } | 102 } |
| 103 | 103 |
| 104 /** | 104 /** |
| 105 * Returns the type arguments of [target] as an instance of [substitutionName]. | 105 * Returns the type arguments of [target] as an instance of [substitutionName]. |
| 106 */ | 106 */ |
| 107 getRuntimeTypeArguments(target, substitutionName) { | 107 getRuntimeTypeArguments(target, substitutionName) { |
| 108 var substitution = | 108 var substitution = |
| 109 getField(target, '${JS_OPERATOR_AS_PREFIX()}$substitutionName'); | 109 getField(target, '${JS_GET_NAME(JsGetName.OPERATOR_AS_PREFIX)}$substitutio nName'); |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 110 return substitute(substitution, getRuntimeTypeInfo(target)); | 110 return substitute(substitution, getRuntimeTypeInfo(target)); |
| 111 } | 111 } |
| 112 | 112 |
| 113 /** | 113 /** |
| 114 * Returns the [index]th type argument of [target] as an instance of | 114 * Returns the [index]th type argument of [target] as an instance of |
| 115 * [substitutionName]. | 115 * [substitutionName]. |
| 116 */ | 116 */ |
| 117 @NoThrows() @NoSideEffects() @NoInline() | 117 @NoThrows() @NoSideEffects() @NoInline() |
| 118 getRuntimeTypeArgument(Object target, String substitutionName, int index) { | 118 getRuntimeTypeArgument(Object target, String substitutionName, int index) { |
| 119 var arguments = getRuntimeTypeArguments(target, substitutionName); | 119 var arguments = getRuntimeTypeArguments(target, substitutionName); |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 if (rti != null) { | 385 if (rti != null) { |
| 386 // If the type has type variables (that is, `rti != null`), make a copy of | 386 // If the type has type variables (that is, `rti != null`), make a copy of |
| 387 // the type arguments and insert [o] in the first position to create a | 387 // the type arguments and insert [o] in the first position to create a |
| 388 // compound type representation. | 388 // compound type representation. |
| 389 rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy. | 389 rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy. |
| 390 JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0. | 390 JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0. |
| 391 type = rti; | 391 type = rti; |
| 392 } else if (isDartFunctionType(t)) { | 392 } else if (isDartFunctionType(t)) { |
| 393 // Functions are treated specially and have their type information stored | 393 // Functions are treated specially and have their type information stored |
| 394 // directly in the instance. | 394 // directly in the instance. |
| 395 var targetSignatureFunction = getField(o, '${JS_SIGNATURE_NAME()}'); | 395 var targetSignatureFunction = getField(o, '${JS_GET_NAME(JsGetName.SIGNATURE _NAME)}'); |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 396 if (targetSignatureFunction == null) return false; | 396 if (targetSignatureFunction == null) return false; |
| 397 type = invokeOn(targetSignatureFunction, o, null); | 397 type = invokeOn(targetSignatureFunction, o, null); |
| 398 return isFunctionSubtype(type, t); | 398 return isFunctionSubtype(type, t); |
| 399 } | 399 } |
| 400 return isSubtype(type, t); | 400 return isSubtype(type, t); |
| 401 } | 401 } |
| 402 | 402 |
| 403 Object subtypeOfRuntimeTypeCast(Object object, var type) { | 403 Object subtypeOfRuntimeTypeCast(Object object, var type) { |
| 404 if (object != null && !checkSubtypeOfRuntimeType(object, type)) { | 404 if (object != null && !checkSubtypeOfRuntimeType(object, type)) { |
| 405 String actualType = Primitives.objectTypeName(object); | 405 String actualType = Primitives.objectTypeName(object); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 452 var typeOfT = isJsArray(t) ? getIndex(t, 0) : t; | 452 var typeOfT = isJsArray(t) ? getIndex(t, 0) : t; |
| 453 | 453 |
| 454 // Check for a subtyping flag. | 454 // Check for a subtyping flag. |
| 455 // Get the necessary substitution of the type arguments, if there is one. | 455 // Get the necessary substitution of the type arguments, if there is one. |
| 456 var substitution; | 456 var substitution; |
| 457 if (isNotIdentical(typeOfT, typeOfS)) { | 457 if (isNotIdentical(typeOfT, typeOfS)) { |
| 458 if (!builtinIsSubtype(typeOfS, runtimeTypeToString(typeOfT))) { | 458 if (!builtinIsSubtype(typeOfS, runtimeTypeToString(typeOfT))) { |
| 459 return false; | 459 return false; |
| 460 } | 460 } |
| 461 var typeOfSPrototype = JS('', '#.prototype', typeOfS); | 461 var typeOfSPrototype = JS('', '#.prototype', typeOfS); |
| 462 var field = '${JS_OPERATOR_AS_PREFIX()}${runtimeTypeToString(typeOfT)}'; | 462 var field = '${JS_GET_NAME(JsGetName.OPERATOR_AS_PREFIX)}${runtimeTypeToStri ng(typeOfT)}'; |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 463 substitution = getField(typeOfSPrototype, field); | 463 substitution = getField(typeOfSPrototype, field); |
| 464 } | 464 } |
| 465 // The class of [s] is a subclass of the class of [t]. If [s] has no type | 465 // The class of [s] is a subclass of the class of [t]. If [s] has no type |
| 466 // arguments and no substitution, it is used as raw type. If [t] has no | 466 // arguments and no substitution, it is used as raw type. If [t] has no |
| 467 // type arguments, it used as a raw type. In both cases, [s] is a subtype | 467 // type arguments, it used as a raw type. In both cases, [s] is a subtype |
| 468 // of [t]. | 468 // of [t]. |
| 469 if ((!isJsArray(s) && substitution == null) || !isJsArray(t)) { | 469 if ((!isJsArray(s) && substitution == null) || !isJsArray(t)) { |
| 470 return true; | 470 return true; |
| 471 } | 471 } |
| 472 // Recursively check the type arguments. | 472 // Recursively check the type arguments. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 var tType = JS('', '#[#]', t, name); | 524 var tType = JS('', '#[#]', t, name); |
| 525 var sType = JS('', '#[#]', s, name); | 525 var sType = JS('', '#[#]', s, name); |
| 526 if (!isAssignable(tType, sType)) return false; | 526 if (!isAssignable(tType, sType)) return false; |
| 527 } | 527 } |
| 528 return true; | 528 return true; |
| 529 } | 529 } |
| 530 | 530 |
| 531 bool isFunctionSubtype(var s, var t) { | 531 bool isFunctionSubtype(var s, var t) { |
| 532 assert(isDartFunctionType(t)); | 532 assert(isDartFunctionType(t)); |
| 533 if (!isDartFunctionType(s)) return false; | 533 if (!isDartFunctionType(s)) return false; |
| 534 if (hasField(s, '${JS_FUNCTION_TYPE_VOID_RETURN_TAG()}')) { | 534 if (hasField(s, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG)}')) { |
| 535 if (hasNoField(t, '${JS_FUNCTION_TYPE_VOID_RETURN_TAG()}') && | 535 if (hasNoField(t, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG)}') && |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 536 hasField(t, '${JS_FUNCTION_TYPE_RETURN_TYPE_TAG()}')) { | 536 hasField(t, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG)}')) { |
|
herhut
2015/06/03 08:58:29
Long line...
| |
| 537 return false; | 537 return false; |
| 538 } | 538 } |
| 539 } else if (hasNoField(t, '${JS_FUNCTION_TYPE_VOID_RETURN_TAG()}')) { | 539 } else if (hasNoField(t, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TA G)}')) { |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 540 var sReturnType = getField(s, '${JS_FUNCTION_TYPE_RETURN_TYPE_TAG()}'); | 540 var sReturnType = getField(s, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_ TYPE_TAG)}'); |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 541 var tReturnType = getField(t, '${JS_FUNCTION_TYPE_RETURN_TYPE_TAG()}'); | 541 var tReturnType = getField(t, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_ TYPE_TAG)}'); |
|
herhut
2015/06/03 08:58:29
Long line...
| |
| 542 if (!isAssignable(sReturnType, tReturnType)) return false; | 542 if (!isAssignable(sReturnType, tReturnType)) return false; |
| 543 } | 543 } |
| 544 var sParameterTypes = | 544 var sParameterTypes = |
| 545 getField(s, '${JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG()}'); | 545 getField(s, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG )}'); |
| 546 var tParameterTypes = | 546 var tParameterTypes = |
| 547 getField(t, '${JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG()}'); | 547 getField(t, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG )}'); |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 548 | 548 |
| 549 var sOptionalParameterTypes = | 549 var sOptionalParameterTypes = |
| 550 getField(s, '${JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG()}'); | 550 getField(s, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG )}'); |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 551 var tOptionalParameterTypes = | 551 var tOptionalParameterTypes = |
| 552 getField(t, '${JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG()}'); | 552 getField(t, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG )}'); |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 553 | 553 |
| 554 int sParametersLen = sParameterTypes != null ? getLength(sParameterTypes) : 0; | 554 int sParametersLen = sParameterTypes != null ? getLength(sParameterTypes) : 0; |
| 555 int tParametersLen = tParameterTypes != null ? getLength(tParameterTypes) : 0; | 555 int tParametersLen = tParameterTypes != null ? getLength(tParameterTypes) : 0; |
| 556 | 556 |
| 557 int sOptionalParametersLen = | 557 int sOptionalParametersLen = |
| 558 sOptionalParameterTypes != null ? getLength(sOptionalParameterTypes) : 0; | 558 sOptionalParameterTypes != null ? getLength(sOptionalParameterTypes) : 0; |
| 559 int tOptionalParametersLen = | 559 int tOptionalParametersLen = |
| 560 tOptionalParameterTypes != null ? getLength(tOptionalParameterTypes) : 0; | 560 tOptionalParameterTypes != null ? getLength(tOptionalParameterTypes) : 0; |
| 561 | 561 |
| 562 if (sParametersLen > tParametersLen) { | 562 if (sParametersLen > tParametersLen) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 // parameters of [s]: | 600 // parameters of [s]: |
| 601 for (; tPos < tOptionalParametersLen ; sPos++, tPos++) { | 601 for (; tPos < tOptionalParametersLen ; sPos++, tPos++) { |
| 602 if (!isAssignable(getIndex(sOptionalParameterTypes, sPos), | 602 if (!isAssignable(getIndex(sOptionalParameterTypes, sPos), |
| 603 getIndex(tOptionalParameterTypes, tPos))) { | 603 getIndex(tOptionalParameterTypes, tPos))) { |
| 604 return false; | 604 return false; |
| 605 } | 605 } |
| 606 } | 606 } |
| 607 } | 607 } |
| 608 | 608 |
| 609 var sNamedParameters = | 609 var sNamedParameters = |
| 610 getField(s, '${JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG()}'); | 610 getField(s, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG)}' ); |
|
herhut
2015/06/03 08:58:29
Long line...
| |
| 611 var tNamedParameters = | 611 var tNamedParameters = |
| 612 getField(t, '${JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG()}'); | 612 getField(t, '${JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG)}' ); |
|
herhut
2015/06/03 08:58:28
Long line...
| |
| 613 return areAssignableMaps(sNamedParameters, tNamedParameters); | 613 return areAssignableMaps(sNamedParameters, tNamedParameters); |
| 614 } | 614 } |
| 615 | 615 |
| 616 /** | 616 /** |
| 617 * Calls the JavaScript [function] with the [arguments] with the global scope | 617 * Calls the JavaScript [function] with the [arguments] with the global scope |
| 618 * as the `this` context. | 618 * as the `this` context. |
| 619 */ | 619 */ |
| 620 invoke(var function, var arguments) => invokeOn(function, null, arguments); | 620 invoke(var function, var arguments) => invokeOn(function, null, arguments); |
| 621 | 621 |
| 622 /** | 622 /** |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 * `null` and `undefined` (which we can avoid). | 668 * `null` and `undefined` (which we can avoid). |
| 669 */ | 669 */ |
| 670 bool isIdentical(var s, var t) => JS('bool', '# === #', s, t); | 670 bool isIdentical(var s, var t) => JS('bool', '# === #', s, t); |
| 671 | 671 |
| 672 /** | 672 /** |
| 673 * Returns `true` if the JavaScript values [s] and [t] are not identical. We use | 673 * Returns `true` if the JavaScript values [s] and [t] are not identical. We use |
| 674 * this helper instead of [identical] because `identical` needs to merge | 674 * this helper instead of [identical] because `identical` needs to merge |
| 675 * `null` and `undefined` (which we can avoid). | 675 * `null` and `undefined` (which we can avoid). |
| 676 */ | 676 */ |
| 677 bool isNotIdentical(var s, var t) => JS('bool', '# !== #', s, t); | 677 bool isNotIdentical(var s, var t) => JS('bool', '# !== #', s, t); |
| OLD | NEW |