| Index: tool/input_sdk/private/ddc_runtime/types.dart
|
| diff --git a/tool/input_sdk/private/ddc_runtime/types.dart b/tool/input_sdk/private/ddc_runtime/types.dart
|
| index 0246c6750e3decf45beb8f9fa4d30548d32e498e..961c82b153ebf903a7b0e78290d294d20e33a11b 100644
|
| --- a/tool/input_sdk/private/ddc_runtime/types.dart
|
| +++ b/tool/input_sdk/private/ddc_runtime/types.dart
|
| @@ -11,9 +11,11 @@ final _mixins = JS('', 'Symbol("mixins")');
|
| final implements_ = JS('', 'Symbol("implements")');
|
| final metadata = JS('', 'Symbol("metadata")');
|
|
|
| +/// The symbol used to store the cached `Type` object associated with a class.
|
| +final _typeObject = JS('', 'Symbol("typeObject")');
|
|
|
| +/// Types in dart are represented internally at runtime as follows.
|
| ///
|
| -/// Types in dart are represented at runtime as follows.
|
| /// - Normal nominal types, produced from classes, are represented
|
| /// at runtime by the JS class of which they are an instance.
|
| /// If the type is the result of instantiating a generic class,
|
| @@ -33,11 +35,15 @@ final metadata = JS('', 'Symbol("metadata")');
|
| /// - As an instance of TypeDef. The TypeDef representation lazily
|
| /// computes an instance of FunctionType, and delegates to that instance.
|
| ///
|
| -/// All types satisfy the following interface:
|
| -/// get String name;
|
| -/// String toString();
|
| -///
|
| +/// These above "runtime types" are what is used for implementing DDC's
|
| +/// internal type checks. These objects are distinct from the objects exposed
|
| +/// to user code by class literals and calling `Object.runtimeType`. In DDC,
|
| +/// the latter are represented by instances of WrappedType which contain a
|
| +/// real runtime type internally. This ensures that the returned object only
|
| +/// exposes the API that Type defines:
|
| ///
|
| +/// get String name;
|
| +/// String toString();
|
| final TypeRep = JS('', '''
|
| class TypeRep {
|
| get name() { return this.toString(); }
|
| @@ -75,6 +81,16 @@ final JSObject = JS('', '''
|
| ''');
|
| final jsobject = JS('', 'new $JSObject()');
|
|
|
| +final WrappedType = JS('', '''
|
| + class WrappedType extends $TypeRep {
|
| + constructor(type) {
|
| + super();
|
| + this._runtimeType = type;
|
| + }
|
| + toString() { return $typeName(this._runtimeType); }
|
| + }
|
| +''');
|
| +
|
| final AbstractFunctionType = JS('', '''
|
| class AbstractFunctionType extends $TypeRep {
|
| constructor() {
|
| @@ -286,15 +302,26 @@ typeName(type) => JS('', '''(() => {
|
| if (tag === $Type) {
|
| let name = $type.name;
|
| let args = $getGenericArgs($type);
|
| - if (args) {
|
| - name += '<';
|
| - for (let i = 0; i < args.length; ++i) {
|
| - if (i > 0) name += ', ';
|
| - name += $typeName(args[i]);
|
| - }
|
| - name += '>';
|
| + if (!args) return name;
|
| +
|
| + let result = name;
|
| + let allDynamic = true;
|
| +
|
| + result += '<';
|
| + for (let i = 0; i < args.length; ++i) {
|
| + if (i > 0) name += ', ';
|
| +
|
| + let argName = $typeName(args[i]);
|
| + if (argName != 'dynamic') allDynamic = false;
|
| +
|
| + result += argName;
|
| }
|
| - return name;
|
| + result += '>';
|
| +
|
| + // Don't print the type arguments if they are all dynamic. Show "raw"
|
| + // types as just the bare type name.
|
| + if (allDynamic) return name;
|
| + return result;
|
| }
|
| if (tag) return "Not a type: " + tag.name;
|
| return "JSObject<" + $type.name + ">";
|
|
|