| Index: lib/src/compiler/code_generator.dart
|
| diff --git a/lib/src/compiler/code_generator.dart b/lib/src/compiler/code_generator.dart
|
| index ed3d017fa31159a6bf1b1081c5e101c300cad977..6a290fdc453914ca640d4ee0db7097343582041b 100644
|
| --- a/lib/src/compiler/code_generator.dart
|
| +++ b/lib/src/compiler/code_generator.dart
|
| @@ -1655,9 +1655,9 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| }
|
|
|
| // TODO(jmesserly): various problems here, see:
|
| - // https://github.com/dart-lang/dev_compiler/issues/161
|
| + // https://github.com/dart-lang/dev_compiler/issues/116
|
| var paramType = param.element.type;
|
| - if (!constructor && _hasUnsoundTypeParameter(paramType)) {
|
| + if (node is MethodDeclaration && _unsoundCovariant(paramType, true)) {
|
| body.add(
|
| js.statement('dart.as(#, #);', [jsParam, _emitType(paramType)]));
|
| }
|
| @@ -1665,12 +1665,22 @@ class CodeGenerator extends GeneralizingAstVisitor
|
| return body.isEmpty ? null : _statement(body);
|
| }
|
|
|
| - bool _isUnsoundTypeParameter(DartType t) =>
|
| - t is TypeParameterType && t.element.enclosingElement is ClassElement;
|
| -
|
| - bool _hasUnsoundTypeParameter(DartType t) =>
|
| - _isUnsoundTypeParameter(t) ||
|
| - t is ParameterizedType && t.typeArguments.any(_hasUnsoundTypeParameter);
|
| + /// Given a type [t], return whether or not t is unsoundly covariant.
|
| + /// If [contravariant] is true, then t appears in a contravariant
|
| + /// position.
|
| + bool _unsoundCovariant(DartType t, bool contravariant) {
|
| + if (t is TypeParameterType) {
|
| + return contravariant && t.element.enclosingElement is ClassElement;
|
| + }
|
| + if (t is FunctionType) {
|
| + if (_unsoundCovariant(t.returnType, contravariant)) return true;
|
| + return t.parameters.any((p) => _unsoundCovariant(p.type, !contravariant));
|
| + }
|
| + if (t is ParameterizedType) {
|
| + return t.typeArguments.any((t) => _unsoundCovariant(t, contravariant));
|
| + }
|
| + return false;
|
| + }
|
|
|
| JS.Expression _defaultParamValue(FormalParameter param) {
|
| if (param is DefaultFormalParameter && param.defaultValue != null) {
|
|
|