| Index: lib/src/compiler/code_generator.dart
|
| diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart
|
| index f758d14bbcabe38bcf874d80a1988036442dae46..cd63211b8dd6f0a6f2636253bd20684368b14d6b 100644
|
| --- a/lib/src/compiler/code_generator.dart
|
| +++ b/lib/src/compiler/code_generator.dart
|
| @@ -458,7 +458,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| return fromExpr;
|
| }
|
|
|
| - return js.call('dart.as(#, #)', [fromExpr, _emitTypeName(to)]);
|
| + return js.call('dart.as(#, #)', [fromExpr, _emitType(to)]);
|
| }
|
|
|
| @override
|
| @@ -472,7 +472,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| result = js.call('typeof # == #', [lhs, js.string(typeofName, "'")]);
|
| } else {
|
| // Always go through a runtime helper, because implicit interfaces.
|
| - result = js.call('dart.is(#, #)', [lhs, _emitTypeName(type)]);
|
| + result = js.call('dart.is(#, #)', [lhs, _emitType(type)]);
|
| }
|
|
|
| if (node.notOperator != null) {
|
| @@ -495,7 +495,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| JS.Expression body = annotate(
|
| js.call('dart.typedef(#, () => #)', [
|
| js.string(element.name, "'"),
|
| - _emitTypeName(element.type, lowerTypedef: true)
|
| + _emitType(element.type, lowerTypedef: true)
|
| ]),
|
| node,
|
| element);
|
| @@ -513,7 +513,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| JS.Expression visitTypeName(TypeName node) {
|
| // TODO(jmesserly): should only happen for erroneous code.
|
| if (node.type == null) return js.call('dart.dynamic');
|
| - return _emitTypeName(node.type);
|
| + return _emitType(node.type);
|
| }
|
|
|
| @override
|
| @@ -741,7 +741,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| var values = new JS.ArrayInitializer(new List<JS.Expression>.from(
|
| fields.map((f) => js.call('#.#', [id, f.name]))));
|
| result.add(js.statement('#.values = dart.const(dart.list(#, #));',
|
| - [id, values, _emitTypeName(type)]));
|
| + [id, values, _emitType(type)]));
|
|
|
| return _statement(result);
|
| }
|
| @@ -759,7 +759,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| ]);
|
|
|
| var dynType = fillDynamicTypeArgs(element.type);
|
| - var genericInst = _emitTypeName(dynType, lowerGeneric: true);
|
| + var genericInst = _emitType(dynType, lowerGeneric: true);
|
| return js.statement(
|
| '{ #; # = #; }', [genericDef, _emitTopLevelName(element), genericInst]);
|
| }
|
| @@ -804,10 +804,10 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| supertype = fillDynamicTypeArgs(supertype.element.type);
|
| _hasDeferredSupertype.add(element);
|
| }
|
| - heritage = _emitTypeName(supertype);
|
| + heritage = _emitType(supertype);
|
|
|
| if (type.mixins.isNotEmpty) {
|
| - var mixins = type.mixins.map(_emitTypeName).toList();
|
| + var mixins = type.mixins.map(_emitType).toList();
|
| mixins.insert(0, heritage);
|
| heritage = js.call('dart.mixin(#)', [mixins]);
|
| }
|
| @@ -1051,7 +1051,8 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| // TODO(jmesserly): we should really just extend Array in the first place.
|
| newBaseClass = js.call('dart.global.#', [jsPeerName]);
|
| } else if (_hasDeferredSupertype.contains(classElem)) {
|
| - newBaseClass = _emitTypeName(classElem.type.superclass);
|
| + newBaseClass = _emitType(classElem.type.superclass,
|
| + subClass: classElem, className: className);
|
| }
|
| if (newBaseClass != null) {
|
| body.add(
|
| @@ -1136,7 +1137,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| body.add(js.statement('#[dart.implements] = () => #;', [
|
| className,
|
| new JS.ArrayInitializer(new List<JS.Expression>.from(
|
| - classElem.interfaces.map(_emitTypeName)))
|
| + classElem.interfaces.map(_emitType)))
|
| ]));
|
| }
|
|
|
| @@ -1608,7 +1609,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| var paramType = param.element.type;
|
| if (!constructor && _hasUnsoundTypeParameter(paramType)) {
|
| body.add(js
|
| - .statement('dart.as(#, #);', [jsParam, _emitTypeName(paramType)]));
|
| + .statement('dart.as(#, #);', [jsParam, _emitType(paramType)]));
|
| }
|
| }
|
| return body.isEmpty ? null : _statement(body);
|
| @@ -1989,7 +1990,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| gen = js.call('#.bind(this)', gen);
|
| }
|
|
|
| - var T = _emitTypeName(returnType);
|
| + var T = _emitType(returnType);
|
| return js.call('dart.#(#)', [
|
| kind,
|
| [gen, T]..addAll(visitFormalParameterList(parameters, destructure: false))
|
| @@ -2052,7 +2053,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
|
|
| // type literal
|
| if (element is TypeDefiningElement) {
|
| - var typeName = _emitTypeName(fillDynamicTypeArgs(element.type));
|
| + var typeName = _emitType(fillDynamicTypeArgs(element.type));
|
|
|
| // If the type is a type literal expression in Dart code, wrap the raw
|
| // runtime type in a "Type" instance.
|
| @@ -2081,7 +2082,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| // library prefix. We don't need those because static calls can't use
|
| // the generic type.
|
| if (isStatic) {
|
| - var dynType = _emitTypeName(fillDynamicTypeArgs(type));
|
| + var dynType = _emitType(fillDynamicTypeArgs(type));
|
| return new JS.PropertyAccess(dynType, member);
|
| }
|
|
|
| @@ -2157,7 +2158,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| for (int i = 0; i < types.length; ++i) {
|
| var metadata =
|
| parameters != null ? _parameterMetadata(parameters[i]) : [];
|
| - var typeName = _emitTypeName(types[i]);
|
| + var typeName = _emitType(types[i]);
|
| var value = typeName;
|
| // TODO(vsm): Make this optional per #268.
|
| if (metadata.isNotEmpty) {
|
| @@ -2173,7 +2174,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| var properties = <JS.Property>[];
|
| types.forEach((name, type) {
|
| var key = _propertyName(name);
|
| - var value = _emitTypeName(type);
|
| + var value = _emitType(type);
|
| properties.add(new JS.Property(key, value));
|
| });
|
| return new JS.ObjectInitializer(properties);
|
| @@ -2186,7 +2187,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| var parameterTypes = type.normalParameterTypes;
|
| var optionalTypes = type.optionalParameterTypes;
|
| var namedTypes = type.namedParameterTypes;
|
| - var rt = _emitTypeName(type.returnType);
|
| + var rt = _emitType(type.returnType);
|
| var ra = _emitTypeNames(parameterTypes, parameters);
|
|
|
| List<JS.Expression> typeParts;
|
| @@ -2221,8 +2222,15 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| /// function type. Similarly if [lowerGeneric] is set, the `List$()` form
|
| /// will be used instead of `List`. These flags are used when generating
|
| /// the definitions for typedefs and generic types, respectively.
|
| - JS.Expression _emitTypeName(DartType type,
|
| - {bool lowerTypedef: false, bool lowerGeneric: false}) {
|
| + ///
|
| + /// If [subClass] is set, then we are setting the base class for the given
|
| + /// class and should emit the given [className], which will already be
|
| + /// defined.
|
| + JS.Expression _emitType(DartType type,
|
| + {bool lowerTypedef: false,
|
| + bool lowerGeneric: false,
|
| + ClassElement subClass,
|
| + JS.Expression className}) {
|
| // The void and dynamic types are not defined in core.
|
| if (type.isVoid) {
|
| return js.call('dart.void');
|
| @@ -2252,11 +2260,16 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| return new JS.Identifier(name);
|
| }
|
|
|
| + if (type == subClass?.type) {
|
| + return className;
|
| + }
|
| +
|
| if (type is ParameterizedType) {
|
| var args = type.typeArguments;
|
| Iterable jsArgs = null;
|
| if (args.any((a) => !a.isDynamic)) {
|
| - jsArgs = args.map(_emitTypeName);
|
| + jsArgs = args.map(
|
| + (x) => _emitType(x, subClass: subClass, className: className));
|
| } else if (lowerGeneric) {
|
| jsArgs = [];
|
| }
|
| @@ -2537,7 +2550,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| f is FunctionType &&
|
| f.typeFormals.isEmpty) {
|
| return _recoverTypeArguments(g, f)
|
| - .map(_emitTypeName)
|
| + .map(_emitType)
|
| .toList(growable: false);
|
| } else if (typeArgs != null) {
|
| // Dynamic calls may have type arguments, even though the function types
|
| @@ -2979,7 +2992,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
|
|
| JS.Expression _emitConstructorName(
|
| ConstructorElement element, DartType type, SimpleIdentifier name) {
|
| - var typeName = _emitTypeName(type);
|
| + var typeName = _emitType(type);
|
| if (name != null || element.isFactory) {
|
| var namedCtor = _constructorName(element);
|
| return new JS.PropertyAccess(typeName, namedCtor);
|
| @@ -3005,7 +3018,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| if (element == null) {
|
| // TODO(jmesserly): this only happens if we had a static error.
|
| // Should we generate a throw instead?
|
| - ctor = _emitTypeName(type);
|
| + ctor = _emitType(type);
|
| if (name != null) {
|
| ctor = new JS.PropertyAccess(ctor, _propertyName(name.name));
|
| }
|
| @@ -3931,7 +3944,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| return new JS.If(
|
| js.call('dart.is(#, #)', [
|
| _visit(_catchParameter),
|
| - _emitTypeName(clause.exceptionType.type),
|
| + _emitType(clause.exceptionType.type),
|
| ]),
|
| then,
|
| otherwise);
|
| @@ -4021,7 +4034,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| // TODO(vsm): When we canonicalize, we need to treat private symbols
|
| // correctly.
|
| var name = js.string(node.components.join('.'), "'");
|
| - return js.call('#.new(#)', [_emitTypeName(types.symbolType), name]);
|
| + return js.call('#.new(#)', [_emitType(types.symbolType), name]);
|
| }
|
| return _emitConst(emitSymbol);
|
| }
|
| @@ -4039,7 +4052,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| if (!elementType.isDynamic) {
|
| // dart.list helper internally depends on _interceptors.JSArray.
|
| _loader.declareBeforeUse(_jsArray);
|
| - list = js.call('dart.list(#, #)', [list, _emitTypeName(elementType)]);
|
| + list = js.call('dart.list(#, #)', [list, _emitType(elementType)]);
|
| }
|
| return list;
|
| }
|
| @@ -4075,7 +4088,7 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| }
|
| var types = <JS.Expression>[];
|
| if (typeArgs != null) {
|
| - types.addAll(typeArgs.arguments.map((e) => _emitTypeName(e.type)));
|
| + types.addAll(typeArgs.arguments.map((e) => _emitType(e.type)));
|
| }
|
| return js.call('dart.map(#, #)', [mapArguments, types]);
|
| }
|
|
|