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 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 // Therefore, dart:core Object gets the one real `constructor` and | 1308 // Therefore, dart:core Object gets the one real `constructor` and |
1309 // immediately bounces to the `new() { ... }` initializer, letting us | 1309 // immediately bounces to the `new() { ... }` initializer, letting us |
1310 // bypass the ES6 restrictions. | 1310 // bypass the ES6 restrictions. |
1311 // | 1311 // |
1312 // TODO(jmesserly): we'll need to rethink this. | 1312 // TODO(jmesserly): we'll need to rethink this. |
1313 // See <https://github.com/dart-lang/dev_compiler/issues/51>. | 1313 // See <https://github.com/dart-lang/dev_compiler/issues/51>. |
1314 // This level of indirection will hurt performance. | 1314 // This level of indirection will hurt performance. |
1315 jsMethods.add(new JS.Method( | 1315 jsMethods.add(new JS.Method( |
1316 _propertyName('constructor'), | 1316 _propertyName('constructor'), |
1317 js.call('function(...args) { return this.new.apply(this, args); }') | 1317 js.call('function(...args) { return this.new.apply(this, args); }') |
1318 as JS.Fun)); | 1318 as JS.Fun)); |
1319 } else if (ctors.isEmpty) { | 1319 } else if (ctors.isEmpty) { |
1320 jsMethods.add(_emitImplicitConstructor(node, fields, virtualFields)); | 1320 jsMethods.add(_emitImplicitConstructor(node, fields, virtualFields)); |
1321 } | 1321 } |
1322 | 1322 |
1323 bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null; | 1323 bool hasJsPeer = findAnnotation(element, isJsPeerInterface) != null; |
1324 | 1324 |
1325 bool hasIterator = false; | 1325 bool hasIterator = false; |
1326 for (var m in node.members) { | 1326 for (var m in node.members) { |
1327 if (m is ConstructorDeclaration) { | 1327 if (m is ConstructorDeclaration) { |
1328 jsMethods | 1328 jsMethods |
(...skipping 2060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3389 | 3389 |
3390 var target = _getTarget(node); | 3390 var target = _getTarget(node); |
3391 if (target == null || isLibraryPrefix(target)) { | 3391 if (target == null || isLibraryPrefix(target)) { |
3392 return _emitFunctionCall(node); | 3392 return _emitFunctionCall(node); |
3393 } | 3393 } |
3394 if (node.methodName.name == 'call') { | 3394 if (node.methodName.name == 'call') { |
3395 var targetType = target.staticType; | 3395 var targetType = target.staticType; |
3396 if (targetType is FunctionType) { | 3396 if (targetType is FunctionType) { |
3397 // Call methods on function types should be handled as regular function | 3397 // Call methods on function types should be handled as regular function |
3398 // invocations. | 3398 // invocations. |
3399 return _emitFunctionCall(node); | 3399 return _emitFunctionCall(node, node.target); |
3400 } | 3400 } |
3401 if (targetType.isDartCoreFunction || targetType.isDynamic) { | 3401 if (targetType.isDartCoreFunction || targetType.isDynamic) { |
3402 // TODO(vsm): Can a call method take generic type parameters? | 3402 // TODO(vsm): Can a call method take generic type parameters? |
3403 return _emitDynamicInvoke(node, _visit(target), | 3403 return _emitDynamicInvoke(node, _visit(target), |
3404 _visit(node.argumentList) as List<JS.Expression>); | 3404 _visit(node.argumentList) as List<JS.Expression>); |
3405 } | 3405 } |
3406 } | 3406 } |
3407 | 3407 |
3408 return _emitMethodCall(target, node); | 3408 return _emitMethodCall(target, node); |
3409 } | 3409 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3536 } else { | 3536 } else { |
3537 if (_inWhitelistCode(node, isCall: true)) { | 3537 if (_inWhitelistCode(node, isCall: true)) { |
3538 return new JS.Call(fn, args); | 3538 return new JS.Call(fn, args); |
3539 } | 3539 } |
3540 return _callHelper('dcall(#, #)', [fn, args]); | 3540 return _callHelper('dcall(#, #)', [fn, args]); |
3541 } | 3541 } |
3542 } | 3542 } |
3543 | 3543 |
3544 /// Emits a function call, to a top-level function, local function, or | 3544 /// Emits a function call, to a top-level function, local function, or |
3545 /// an expression. | 3545 /// an expression. |
3546 JS.Expression _emitFunctionCall(InvocationExpression node) { | 3546 JS.Expression _emitFunctionCall(InvocationExpression node, |
3547 var fn = _visit(node.function); | 3547 [Expression function]) { |
| 3548 if (function == null) { |
| 3549 function = node.function; |
| 3550 } |
| 3551 var fn = _visit(function); |
3548 var args = _visit(node.argumentList) as List<JS.Expression>; | 3552 var args = _visit(node.argumentList) as List<JS.Expression>; |
3549 if (isDynamicInvoke(node.function)) { | 3553 if (isDynamicInvoke(function)) { |
3550 return _emitDynamicInvoke(node, fn, args); | 3554 return _emitDynamicInvoke(node, fn, args); |
3551 } else { | 3555 } else { |
3552 return new JS.Call(_applyInvokeTypeArguments(fn, node), args); | 3556 return new JS.Call(_applyInvokeTypeArguments(fn, node), args); |
3553 } | 3557 } |
3554 } | 3558 } |
3555 | 3559 |
3556 JS.Expression _applyInvokeTypeArguments( | 3560 JS.Expression _applyInvokeTypeArguments( |
3557 JS.Expression target, InvocationExpression node) { | 3561 JS.Expression target, InvocationExpression node) { |
3558 var typeArgs = _emitInvokeTypeArguments(node); | 3562 var typeArgs = _emitInvokeTypeArguments(node); |
3559 if (typeArgs == null) return target; | 3563 if (typeArgs == null) return target; |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3961 Element target, List<VariableDeclaration> fields) { | 3965 Element target, List<VariableDeclaration> fields) { |
3962 var methods = []; | 3966 var methods = []; |
3963 for (var node in fields) { | 3967 for (var node in fields) { |
3964 var name = node.name.name; | 3968 var name = node.name.name; |
3965 var element = node.element; | 3969 var element = node.element; |
3966 var access = _emitMemberName(name, isStatic: true); | 3970 var access = _emitMemberName(name, isStatic: true); |
3967 methods.add(annotate( | 3971 methods.add(annotate( |
3968 new JS.Method( | 3972 new JS.Method( |
3969 access, | 3973 access, |
3970 js.call('function() { return #; }', _visitInitializer(node)) | 3974 js.call('function() { return #; }', _visitInitializer(node)) |
3971 as JS.Fun, | 3975 as JS.Fun, |
3972 isGetter: true), | 3976 isGetter: true), |
3973 node, | 3977 node, |
3974 _findAccessor(element, getter: true))); | 3978 _findAccessor(element, getter: true))); |
3975 | 3979 |
3976 // TODO(jmesserly): currently uses a dummy setter to indicate writable. | 3980 // TODO(jmesserly): currently uses a dummy setter to indicate writable. |
3977 if (!node.isFinal && !node.isConst) { | 3981 if (!node.isFinal && !node.isConst) { |
3978 methods.add(annotate( | 3982 methods.add(annotate( |
3979 new JS.Method(access, js.call('function(_) {}') as JS.Fun, | 3983 new JS.Method(access, js.call('function(_) {}') as JS.Fun, |
3980 isSetter: true), | 3984 isSetter: true), |
3981 node, | 3985 node, |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4521 _bindValue(scope, 'o', _getTarget(prop), context: context), | 4525 _bindValue(scope, 'o', _getTarget(prop), context: context), |
4522 prop.operator, | 4526 prop.operator, |
4523 prop.propertyName); | 4527 prop.propertyName); |
4524 } else if (expr is PrefixedIdentifier) { | 4528 } else if (expr is PrefixedIdentifier) { |
4525 PrefixedIdentifier ident = expr; | 4529 PrefixedIdentifier ident = expr; |
4526 if (isLibraryPrefix(ident.prefix)) { | 4530 if (isLibraryPrefix(ident.prefix)) { |
4527 return expr; | 4531 return expr; |
4528 } | 4532 } |
4529 result = astFactory.prefixedIdentifier( | 4533 result = astFactory.prefixedIdentifier( |
4530 _bindValue(scope, 'o', ident.prefix, context: context) | 4534 _bindValue(scope, 'o', ident.prefix, context: context) |
4531 as SimpleIdentifier, | 4535 as SimpleIdentifier, |
4532 ident.period, | 4536 ident.period, |
4533 ident.identifier); | 4537 ident.identifier); |
4534 } else { | 4538 } else { |
4535 return expr as SimpleIdentifier; | 4539 return expr as SimpleIdentifier; |
4536 } | 4540 } |
4537 result.staticType = expr.staticType; | 4541 result.staticType = expr.staticType; |
4538 setIsDynamicInvoke(result, isDynamicInvoke(expr)); | 4542 setIsDynamicInvoke(result, isDynamicInvoke(expr)); |
4539 return result; | 4543 return result; |
4540 } | 4544 } |
4541 | 4545 |
(...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5766 var targetIdentifier = target as SimpleIdentifier; | 5770 var targetIdentifier = target as SimpleIdentifier; |
5767 | 5771 |
5768 if (targetIdentifier.staticElement is! PrefixElement) return false; | 5772 if (targetIdentifier.staticElement is! PrefixElement) return false; |
5769 var prefix = targetIdentifier.staticElement as PrefixElement; | 5773 var prefix = targetIdentifier.staticElement as PrefixElement; |
5770 | 5774 |
5771 // The library the prefix is referring to must come from a deferred import. | 5775 // The library the prefix is referring to must come from a deferred import. |
5772 var containingLibrary = (target.root as CompilationUnit).element.library; | 5776 var containingLibrary = (target.root as CompilationUnit).element.library; |
5773 var imports = containingLibrary.getImportsWithPrefix(prefix); | 5777 var imports = containingLibrary.getImportsWithPrefix(prefix); |
5774 return imports.length == 1 && imports[0].isDeferred; | 5778 return imports.length == 1 && imports[0].isDeferred; |
5775 } | 5779 } |
OLD | NEW |