OLD | NEW |
---|---|
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 import 'dart:collection' show HashMap, HashSet; | 5 import 'dart:collection' show HashMap, HashSet; |
6 import 'dart:math' show min, max; | 6 import 'dart:math' show min, max; |
7 | 7 |
8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
(...skipping 1637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1648 paramName, | 1648 paramName, |
1649 _defaultParamValue(param), | 1649 _defaultParamValue(param), |
1650 ])); | 1650 ])); |
1651 } else if (param.kind == ParameterKind.POSITIONAL) { | 1651 } else if (param.kind == ParameterKind.POSITIONAL) { |
1652 body.add(js.statement('if (# === void 0) # = #;', | 1652 body.add(js.statement('if (# === void 0) # = #;', |
1653 [jsParam, jsParam, _defaultParamValue(param)])); | 1653 [jsParam, jsParam, _defaultParamValue(param)])); |
1654 } | 1654 } |
1655 } | 1655 } |
1656 | 1656 |
1657 // TODO(jmesserly): various problems here, see: | 1657 // TODO(jmesserly): various problems here, see: |
1658 // https://github.com/dart-lang/dev_compiler/issues/161 | 1658 // https://github.com/dart-lang/dev_compiler/issues/116 |
1659 var paramType = param.element.type; | 1659 var paramType = param.element.type; |
1660 if (!constructor && _hasUnsoundTypeParameter(paramType)) { | 1660 if (node is MethodDeclaration && _unsoundCovariant(paramType, true)) { |
1661 body.add( | 1661 body.add( |
1662 js.statement('dart.as(#, #);', [jsParam, _emitType(paramType)])); | 1662 js.statement('dart.as(#, #);', [jsParam, _emitType(paramType)])); |
1663 } | 1663 } |
1664 } | 1664 } |
1665 return body.isEmpty ? null : _statement(body); | 1665 return body.isEmpty ? null : _statement(body); |
1666 } | 1666 } |
1667 | 1667 |
1668 bool _isUnsoundTypeParameter(DartType t) => | 1668 /// Given a type [t], return whether or not t is unsoundly covariant. |
1669 t is TypeParameterType && t.element.enclosingElement is ClassElement; | 1669 /// If [contravariant] is true, then t appears in a contravariant |
1670 | 1670 /// position. |
1671 bool _hasUnsoundTypeParameter(DartType t) => | 1671 bool _unsoundCovariant(DartType t, bool contravariant) { |
1672 _isUnsoundTypeParameter(t) || | 1672 if (t is TypeParameterType) { |
1673 t is ParameterizedType && t.typeArguments.any(_hasUnsoundTypeParameter); | 1673 return contravariant && t.element.enclosingElement is ClassElement; |
1674 } | |
1675 if (t is FunctionType) { | |
1676 if (_unsoundCovariant(t.returnType, contravariant)) return true; | |
1677 var parameters = t.parameters.map((p) => p.type); | |
Jennifer Messerly
2016/05/17 18:09:04
probably a bit faster to merge this with the .any
Leaf
2016/05/17 18:15:36
Done.
| |
1678 return parameters.any((t) => _unsoundCovariant(t, !contravariant)); | |
1679 } | |
1680 if (t is ParameterizedType) { | |
1681 return t.typeArguments.any((t) => _unsoundCovariant(t, contravariant)); | |
1682 } | |
1683 return false; | |
1684 } | |
1674 | 1685 |
1675 JS.Expression _defaultParamValue(FormalParameter param) { | 1686 JS.Expression _defaultParamValue(FormalParameter param) { |
1676 if (param is DefaultFormalParameter && param.defaultValue != null) { | 1687 if (param is DefaultFormalParameter && param.defaultValue != null) { |
1677 return _visit(param.defaultValue); | 1688 return _visit(param.defaultValue); |
1678 } else { | 1689 } else { |
1679 return new JS.LiteralNull(); | 1690 return new JS.LiteralNull(); |
1680 } | 1691 } |
1681 } | 1692 } |
1682 | 1693 |
1683 JS.Fun _emitNativeFunctionBody(MethodDeclaration node) { | 1694 JS.Fun _emitNativeFunctionBody(MethodDeclaration node) { |
(...skipping 2787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4471 } | 4482 } |
4472 | 4483 |
4473 bool isLibraryPrefix(Expression node) => | 4484 bool isLibraryPrefix(Expression node) => |
4474 node is SimpleIdentifier && node.staticElement is PrefixElement; | 4485 node is SimpleIdentifier && node.staticElement is PrefixElement; |
4475 | 4486 |
4476 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 4487 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
4477 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 4488 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
4478 | 4489 |
4479 bool _isDartRuntime(LibraryElement l) => | 4490 bool _isDartRuntime(LibraryElement l) => |
4480 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 4491 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
OLD | NEW |