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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 } | 542 } |
543 | 543 |
544 // A no-op in JavaScript. | 544 // A no-op in JavaScript. |
545 return jsFrom; | 545 return jsFrom; |
546 } | 546 } |
547 | 547 |
548 var type = _emitType(to, | 548 var type = _emitType(to, |
549 nameType: options.nameTypeTests || options.hoistTypeTests, | 549 nameType: options.nameTypeTests || options.hoistTypeTests, |
550 hoistType: options.hoistTypeTests); | 550 hoistType: options.hoistTypeTests); |
551 if (_inAngularTemplate) return jsFrom; | 551 if (_inAngularTemplate) return jsFrom; |
552 return js.call('dart.as(#, #)', [jsFrom, type]); | 552 if (isReifiedCoercion(node)) { |
| 553 return js.call('dart.check(#, #)', [jsFrom, type]); |
| 554 } else { |
| 555 return js.call('dart.as(#, #)', [jsFrom, type]); |
| 556 } |
| 557 } |
| 558 |
| 559 bool isReifiedCoercion(AstNode node) { |
| 560 // TODO(sra): Find a better way to recognize reified coercion, since we |
| 561 // can't set the isSynthetic attribute. |
| 562 return (node is AsExpression) && (node.asOperator.offset == 0); |
553 } | 563 } |
554 | 564 |
555 @override | 565 @override |
556 visitIsExpression(IsExpression node) { | 566 visitIsExpression(IsExpression node) { |
557 // Generate `is` as `dart.is` or `typeof` depending on the RHS type. | 567 // Generate `is` as `dart.is` or `typeof` depending on the RHS type. |
558 JS.Expression result; | 568 JS.Expression result; |
559 var type = node.type.type; | 569 var type = node.type.type; |
560 var lhs = _visit(node.expression); | 570 var lhs = _visit(node.expression); |
561 var typeofName = _jsTypeofName(type); | 571 var typeofName = _jsTypeofName(type); |
562 if (typeofName != null) { | 572 if (typeofName != null) { |
(...skipping 3832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4395 } | 4405 } |
4396 if (node is BinaryExpression) { | 4406 if (node is BinaryExpression) { |
4397 JS.Expression shortCircuit(String code) { | 4407 JS.Expression shortCircuit(String code) { |
4398 return finish(js.call(code, | 4408 return finish(js.call(code, |
4399 [_visitTest(node.leftOperand), _visitTest(node.rightOperand)])); | 4409 [_visitTest(node.leftOperand), _visitTest(node.rightOperand)])); |
4400 } | 4410 } |
4401 var op = node.operator.type.lexeme; | 4411 var op = node.operator.type.lexeme; |
4402 if (op == '&&') return shortCircuit('# && #'); | 4412 if (op == '&&') return shortCircuit('# && #'); |
4403 if (op == '||') return shortCircuit('# || #'); | 4413 if (op == '||') return shortCircuit('# || #'); |
4404 } | 4414 } |
4405 // Offset 0 from start of file is syntactically impossible for normal code. | 4415 if (isReifiedCoercion(node)) { |
4406 // TODO(sra): Find a better way to recognize reified coercion, since we | 4416 AsExpression asNode = node; |
4407 // can't set the isSynthetic attribute. | 4417 assert(asNode.staticType == types.boolType); |
4408 if (node is AsExpression && node.asOperator.offset == 0) { | 4418 return js.call('dart.test(#)', _visit(asNode.expression)); |
4409 assert(node.staticType == types.boolType); | |
4410 return js.call('dart.test(#)', _visit(node.expression)); | |
4411 } | 4419 } |
4412 JS.Expression result = _visit(node); | 4420 JS.Expression result = _visit(node); |
4413 if (isNullable(node)) result = js.call('dart.test(#)', result); | 4421 if (isNullable(node)) result = js.call('dart.test(#)', result); |
4414 return result; | 4422 return result; |
4415 } | 4423 } |
4416 | 4424 |
4417 /// Like [_emitMemberName], but for declaration sites. | 4425 /// Like [_emitMemberName], but for declaration sites. |
4418 /// | 4426 /// |
4419 /// Unlike call sites, we always have an element available, so we can use it | 4427 /// Unlike call sites, we always have an element available, so we can use it |
4420 /// directly rather than computing the relevant options for [_emitMemberName]. | 4428 /// directly rather than computing the relevant options for [_emitMemberName]. |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4664 } | 4672 } |
4665 | 4673 |
4666 bool isLibraryPrefix(Expression node) => | 4674 bool isLibraryPrefix(Expression node) => |
4667 node is SimpleIdentifier && node.staticElement is PrefixElement; | 4675 node is SimpleIdentifier && node.staticElement is PrefixElement; |
4668 | 4676 |
4669 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 4677 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
4670 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 4678 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
4671 | 4679 |
4672 bool _isDartRuntime(LibraryElement l) => | 4680 bool _isDartRuntime(LibraryElement l) => |
4673 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 4681 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
OLD | NEW |