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 | 2 |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 import 'dart:collection' show HashMap, HashSet; | 6 import 'dart:collection' show HashMap, HashSet; |
7 import 'dart:math' show min, max; | 7 import 'dart:math' show min, max; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
(...skipping 3256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3267 return new JS.Block(stmts); | 3267 return new JS.Block(stmts); |
3268 } | 3268 } |
3269 | 3269 |
3270 @override | 3270 @override |
3271 JS.Block visitBlock(Block node) => | 3271 JS.Block visitBlock(Block node) => |
3272 new JS.Block(_visitList(node.statements) as List<JS.Statement>, | 3272 new JS.Block(_visitList(node.statements) as List<JS.Statement>, |
3273 isScope: true); | 3273 isScope: true); |
3274 | 3274 |
3275 @override | 3275 @override |
3276 visitMethodInvocation(MethodInvocation node) { | 3276 visitMethodInvocation(MethodInvocation node) { |
| 3277 if (_isDeferredLoadLibrary(node.target, node.methodName)) { |
| 3278 // We are calling loadLibrary() on a deferred library prefix. |
| 3279 return _callHelper('loadLibrary()'); |
| 3280 } |
| 3281 |
3277 if (node.operator?.lexeme == '?.') { | 3282 if (node.operator?.lexeme == '?.') { |
3278 return _emitNullSafe(node); | 3283 return _emitNullSafe(node); |
3279 } | 3284 } |
3280 | 3285 |
3281 var result = _emitForeignJS(node); | 3286 var result = _emitForeignJS(node); |
3282 if (result != null) return result; | 3287 if (result != null) return result; |
3283 | 3288 |
3284 var target = _getTarget(node); | 3289 var target = _getTarget(node); |
3285 if (target == null || isLibraryPrefix(target)) { | 3290 if (target == null || isLibraryPrefix(target)) { |
3286 return _emitFunctionCall(node); | 3291 return _emitFunctionCall(node); |
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4534 } | 4539 } |
4535 | 4540 |
4536 @override | 4541 @override |
4537 JS.This visitThisExpression(ThisExpression node) => new JS.This(); | 4542 JS.This visitThisExpression(ThisExpression node) => new JS.This(); |
4538 | 4543 |
4539 @override | 4544 @override |
4540 JS.Super visitSuperExpression(SuperExpression node) => new JS.Super(); | 4545 JS.Super visitSuperExpression(SuperExpression node) => new JS.Super(); |
4541 | 4546 |
4542 @override | 4547 @override |
4543 visitPrefixedIdentifier(PrefixedIdentifier node) { | 4548 visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 4549 if (_isDeferredLoadLibrary(node.prefix, node.identifier)) { |
| 4550 // We are tearing off "loadLibrary" on a library prefix. |
| 4551 return _callHelper('loadLibrary'); |
| 4552 } |
| 4553 |
4544 if (isLibraryPrefix(node.prefix)) { | 4554 if (isLibraryPrefix(node.prefix)) { |
4545 return _visit(node.identifier); | 4555 return _visit(node.identifier); |
4546 } else { | 4556 } else { |
4547 return _emitAccess(node.prefix, node.identifier, node.staticType); | 4557 return _emitAccess(node.prefix, node.identifier, node.staticType); |
4548 } | 4558 } |
4549 } | 4559 } |
4550 | 4560 |
4551 @override | 4561 @override |
4552 visitPropertyAccess(PropertyAccess node) { | 4562 visitPropertyAccess(PropertyAccess node) { |
4553 if (node.operator.lexeme == '?.') { | 4563 if (node.operator.lexeme == '?.') { |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5571 } | 5581 } |
5572 | 5582 |
5573 bool isLibraryPrefix(Expression node) => | 5583 bool isLibraryPrefix(Expression node) => |
5574 node is SimpleIdentifier && node.staticElement is PrefixElement; | 5584 node is SimpleIdentifier && node.staticElement is PrefixElement; |
5575 | 5585 |
5576 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 5586 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
5577 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 5587 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
5578 | 5588 |
5579 bool _isDartRuntime(LibraryElement l) => | 5589 bool _isDartRuntime(LibraryElement l) => |
5580 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 5590 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
| 5591 |
| 5592 /// Returns `true` if [target] is a prefix for a deferred library and [name] |
| 5593 /// is "loadLibrary". |
| 5594 /// |
| 5595 /// If so, the expression should be compiled to call the runtime's |
| 5596 /// "loadLibrary" helper function. |
| 5597 bool _isDeferredLoadLibrary(Expression target, SimpleIdentifier name) { |
| 5598 if (name.name != "loadLibrary") return false; |
| 5599 |
| 5600 if (target is! SimpleIdentifier) return false; |
| 5601 var targetIdentifier = target as SimpleIdentifier; |
| 5602 |
| 5603 if (targetIdentifier.staticElement is! PrefixElement) return false; |
| 5604 var prefix = targetIdentifier.staticElement as PrefixElement; |
| 5605 |
| 5606 // The library the prefix is referring to must come from a deferred import. |
| 5607 var containingLibrary = (target.root as CompilationUnit).element.library; |
| 5608 var imports = containingLibrary.getImportsWithPrefix(prefix); |
| 5609 return imports.length == 1 && imports[0].isDeferred; |
| 5610 } |
OLD | NEW |