| 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; |
| 11 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
| 12 import 'package:analyzer/dart/element/type.dart'; | 12 import 'package:analyzer/dart/element/type.dart'; |
| 13 import 'package:analyzer/src/dart/ast/token.dart' show StringToken; | 13 import 'package:analyzer/src/dart/ast/token.dart' show StringToken; |
| 14 import 'package:analyzer/src/dart/element/element.dart' | 14 import 'package:analyzer/src/dart/element/element.dart' |
| 15 show LocalVariableElementImpl; | 15 show LocalVariableElementImpl; |
| 16 import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl; | 16 import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl; |
| 17 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 17 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
| 18 import 'package:analyzer/src/generated/resolver.dart' | 18 import 'package:analyzer/src/generated/resolver.dart' |
| 19 show TypeProvider, NamespaceBuilder; | 19 show TypeProvider, NamespaceBuilder; |
| 20 import 'package:analyzer/src/generated/type_system.dart' | 20 import 'package:analyzer/src/generated/type_system.dart' |
| 21 show StrongTypeSystemImpl; | 21 show StrongTypeSystemImpl; |
| 22 import 'package:analyzer/src/summary/summarize_elements.dart' | 22 import 'package:analyzer/src/summary/summarize_elements.dart' |
| 23 show PackageBundleAssembler; | 23 show PackageBundleAssembler; |
| 24 import 'package:analyzer/src/task/strong/info.dart' show DynamicInvoke; | 24 import 'package:analyzer/src/task/strong/ast_properties.dart' |
| 25 show isDynamicInvoke, setIsDynamicInvoke; |
| 25 import 'package:source_maps/source_maps.dart'; | 26 import 'package:source_maps/source_maps.dart'; |
| 26 import 'package:path/path.dart' show separator; | 27 import 'package:path/path.dart' show separator; |
| 27 | 28 |
| 28 import '../closure/closure_annotator.dart' show ClosureAnnotator; | 29 import '../closure/closure_annotator.dart' show ClosureAnnotator; |
| 29 import '../js_ast/js_ast.dart' as JS; | 30 import '../js_ast/js_ast.dart' as JS; |
| 30 import '../js_ast/js_ast.dart' show js; | 31 import '../js_ast/js_ast.dart' show js; |
| 31 import 'ast_builder.dart' show AstBuilder; | 32 import 'ast_builder.dart' show AstBuilder; |
| 32 import 'compiler.dart' | 33 import 'compiler.dart' |
| 33 show BuildUnit, CompilerOptions, JSModuleFile, ModuleFormat; | 34 show BuildUnit, CompilerOptions, JSModuleFile, ModuleFormat; |
| 34 import 'element_helpers.dart'; | 35 import 'element_helpers.dart'; |
| (...skipping 2687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2722 return _emitNullSafeSet(lhs, rhs); | 2723 return _emitNullSafeSet(lhs, rhs); |
| 2723 } | 2724 } |
| 2724 | 2725 |
| 2725 target = _getTarget(lhs); | 2726 target = _getTarget(lhs); |
| 2726 id = lhs.propertyName; | 2727 id = lhs.propertyName; |
| 2727 } else if (lhs is PrefixedIdentifier) { | 2728 } else if (lhs is PrefixedIdentifier) { |
| 2728 target = lhs.prefix; | 2729 target = lhs.prefix; |
| 2729 id = lhs.identifier; | 2730 id = lhs.identifier; |
| 2730 } | 2731 } |
| 2731 | 2732 |
| 2732 if (target != null && DynamicInvoke.get(target)) { | 2733 if (target != null && isDynamicInvoke(target)) { |
| 2733 if (_inWhitelistCode(lhs)) { | 2734 if (_inWhitelistCode(lhs)) { |
| 2734 var vars = <JS.MetaLetVariable, JS.Expression>{}; | 2735 var vars = <JS.MetaLetVariable, JS.Expression>{}; |
| 2735 var l = _visit(_bindValue(vars, 'l', target)); | 2736 var l = _visit(_bindValue(vars, 'l', target)); |
| 2736 var name = _emitMemberName(id.name); | 2737 var name = _emitMemberName(id.name); |
| 2737 return new JS.MetaLet(vars, [ | 2738 return new JS.MetaLet(vars, [ |
| 2738 js.call('(#[(#[dart._extensionType]) ? dartx[#] : #] = #)', | 2739 js.call('(#[(#[dart._extensionType]) ? dartx[#] : #] = #)', |
| 2739 [l, l, name, name, _visit(rhs)]) | 2740 [l, l, name, name, _visit(rhs)]) |
| 2740 ]); | 2741 ]); |
| 2741 } | 2742 } |
| 2742 return js.call('dart.dput(#, #, #)', | 2743 return js.call('dart.dput(#, #, #)', |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2861 MethodInvocation node, | 2862 MethodInvocation node, |
| 2862 List<JS.Expression> args, | 2863 List<JS.Expression> args, |
| 2863 List<JS.Expression> typeArgs) { | 2864 List<JS.Expression> typeArgs) { |
| 2864 var type = getStaticType(target); | 2865 var type = getStaticType(target); |
| 2865 var name = node.methodName.name; | 2866 var name = node.methodName.name; |
| 2866 var element = node.methodName.staticElement; | 2867 var element = node.methodName.staticElement; |
| 2867 bool isStatic = element is ExecutableElement && element.isStatic; | 2868 bool isStatic = element is ExecutableElement && element.isStatic; |
| 2868 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); | 2869 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); |
| 2869 | 2870 |
| 2870 JS.Expression jsTarget = _visit(target); | 2871 JS.Expression jsTarget = _visit(target); |
| 2871 if (DynamicInvoke.get(target) || DynamicInvoke.get(node.methodName)) { | 2872 if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) { |
| 2872 if (_inWhitelistCode(target)) { | 2873 if (_inWhitelistCode(target)) { |
| 2873 var vars = <JS.MetaLetVariable, JS.Expression>{}; | 2874 var vars = <JS.MetaLetVariable, JS.Expression>{}; |
| 2874 var l = _visit(_bindValue(vars, 'l', target)); | 2875 var l = _visit(_bindValue(vars, 'l', target)); |
| 2875 jsTarget = new JS.MetaLet(vars, [ | 2876 jsTarget = new JS.MetaLet(vars, [ |
| 2876 js.call('(#[(#[dart._extensionType]) ? dartx[#] : #])', | 2877 js.call('(#[(#[dart._extensionType]) ? dartx[#] : #])', |
| 2877 [l, l, memberName, memberName,]) | 2878 [l, l, memberName, memberName,]) |
| 2878 ]); | 2879 ]); |
| 2879 if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs); | 2880 if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs); |
| 2880 return new JS.Call(jsTarget, args); | 2881 return new JS.Call(jsTarget, args); |
| 2881 } | 2882 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2895 if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs); | 2896 if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs); |
| 2896 | 2897 |
| 2897 return new JS.Call(jsTarget, args); | 2898 return new JS.Call(jsTarget, args); |
| 2898 } | 2899 } |
| 2899 | 2900 |
| 2900 /// Emits a function call, to a top-level function, local function, or | 2901 /// Emits a function call, to a top-level function, local function, or |
| 2901 /// an expression. | 2902 /// an expression. |
| 2902 JS.Expression _emitFunctionCall(InvocationExpression node) { | 2903 JS.Expression _emitFunctionCall(InvocationExpression node) { |
| 2903 var fn = _visit(node.function); | 2904 var fn = _visit(node.function); |
| 2904 var args = _visit(node.argumentList) as List<JS.Expression>; | 2905 var args = _visit(node.argumentList) as List<JS.Expression>; |
| 2905 if (DynamicInvoke.get(node.function)) { | 2906 if (isDynamicInvoke(node.function)) { |
| 2906 var typeArgs = _emitInvokeTypeArguments(node); | 2907 var typeArgs = _emitInvokeTypeArguments(node); |
| 2907 if (typeArgs != null) { | 2908 if (typeArgs != null) { |
| 2908 return js.call('dart.dgcall(#, #, #)', | 2909 return js.call('dart.dgcall(#, #, #)', |
| 2909 [fn, new JS.ArrayInitializer(typeArgs), args]); | 2910 [fn, new JS.ArrayInitializer(typeArgs), args]); |
| 2910 } else { | 2911 } else { |
| 2911 if (_inWhitelistCode(node, isCall: true)) { | 2912 if (_inWhitelistCode(node, isCall: true)) { |
| 2912 return new JS.Call(fn, args); | 2913 return new JS.Call(fn, args); |
| 2913 } | 2914 } |
| 2914 return js.call('dart.dcall(#, #)', [fn, args]); | 2915 return js.call('dart.dcall(#, #)', [fn, args]); |
| 2915 } | 2916 } |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3771 // LocalVariableElementImpl, so we could repurpose to mean "temp". | 3772 // LocalVariableElementImpl, so we could repurpose to mean "temp". |
| 3772 // * add a new property to LocalVariableElementImpl. | 3773 // * add a new property to LocalVariableElementImpl. |
| 3773 // * create a new subtype of LocalVariableElementImpl to mark a temp. | 3774 // * create a new subtype of LocalVariableElementImpl to mark a temp. |
| 3774 var id = | 3775 var id = |
| 3775 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); | 3776 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); |
| 3776 | 3777 |
| 3777 variable ??= new JS.TemporaryId(name); | 3778 variable ??= new JS.TemporaryId(name); |
| 3778 | 3779 |
| 3779 id.staticElement = new TemporaryVariableElement.forNode(id, variable); | 3780 id.staticElement = new TemporaryVariableElement.forNode(id, variable); |
| 3780 id.staticType = type; | 3781 id.staticType = type; |
| 3781 DynamicInvoke.set(id, type.isDynamic); | 3782 setIsDynamicInvoke(id, type.isDynamic); |
| 3782 addTemporaryVariable(id.staticElement, nullable: nullable); | 3783 addTemporaryVariable(id.staticElement, nullable: nullable); |
| 3783 return id; | 3784 return id; |
| 3784 } | 3785 } |
| 3785 | 3786 |
| 3786 JS.Expression _cacheConst(JS.Expression expr()) { | 3787 JS.Expression _cacheConst(JS.Expression expr()) { |
| 3787 var savedTypeParams = _typeParamInConst; | 3788 var savedTypeParams = _typeParamInConst; |
| 3788 _typeParamInConst = []; | 3789 _typeParamInConst = []; |
| 3789 | 3790 |
| 3790 var jsExpr = expr(); | 3791 var jsExpr = expr(); |
| 3791 | 3792 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3845 } | 3846 } |
| 3846 result = new PrefixedIdentifier( | 3847 result = new PrefixedIdentifier( |
| 3847 _bindValue(scope, 'o', ident.prefix, context: context) | 3848 _bindValue(scope, 'o', ident.prefix, context: context) |
| 3848 as SimpleIdentifier, | 3849 as SimpleIdentifier, |
| 3849 ident.period, | 3850 ident.period, |
| 3850 ident.identifier); | 3851 ident.identifier); |
| 3851 } else { | 3852 } else { |
| 3852 return expr as SimpleIdentifier; | 3853 return expr as SimpleIdentifier; |
| 3853 } | 3854 } |
| 3854 result.staticType = expr.staticType; | 3855 result.staticType = expr.staticType; |
| 3855 DynamicInvoke.set(result, DynamicInvoke.get(expr)); | 3856 setIsDynamicInvoke(result, isDynamicInvoke(expr)); |
| 3856 return result; | 3857 return result; |
| 3857 } | 3858 } |
| 3858 | 3859 |
| 3859 /// Creates a temporary to contain the value of [expr]. The temporary can be | 3860 /// Creates a temporary to contain the value of [expr]. The temporary can be |
| 3860 /// used multiple times in the resulting expression. For example: | 3861 /// used multiple times in the resulting expression. For example: |
| 3861 /// `expr ** 2` could be compiled as `expr * expr`. The temporary scope will | 3862 /// `expr ** 2` could be compiled as `expr * expr`. The temporary scope will |
| 3862 /// ensure `expr` is only evaluated once: `(x => x * x)(expr)`. | 3863 /// ensure `expr` is only evaluated once: `(x => x * x)(expr)`. |
| 3863 /// | 3864 /// |
| 3864 /// If the expression does not end up using `x` more than once, or if those | 3865 /// If the expression does not end up using `x` more than once, or if those |
| 3865 /// expressions can be treated as stateless (e.g. they are non-mutated | 3866 /// expressions can be treated as stateless (e.g. they are non-mutated |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4140 // TODO(jmesserly): handle explicitly passed type args. | 4141 // TODO(jmesserly): handle explicitly passed type args. |
| 4141 if (type == null) return null; | 4142 if (type == null) return null; |
| 4142 return _emitFunctionTypeArguments(type, instantiated); | 4143 return _emitFunctionTypeArguments(type, instantiated); |
| 4143 } | 4144 } |
| 4144 | 4145 |
| 4145 JS.Expression _emitAccessInternal(Expression target, Element member, | 4146 JS.Expression _emitAccessInternal(Expression target, Element member, |
| 4146 String memberName, List<JS.Expression> typeArgs) { | 4147 String memberName, List<JS.Expression> typeArgs) { |
| 4147 bool isStatic = member is ClassMemberElement && member.isStatic; | 4148 bool isStatic = member is ClassMemberElement && member.isStatic; |
| 4148 var name = _emitMemberName(memberName, | 4149 var name = _emitMemberName(memberName, |
| 4149 type: getStaticType(target), isStatic: isStatic); | 4150 type: getStaticType(target), isStatic: isStatic); |
| 4150 if (DynamicInvoke.get(target)) { | 4151 if (isDynamicInvoke(target)) { |
| 4151 if (_inWhitelistCode(target)) { | 4152 if (_inWhitelistCode(target)) { |
| 4152 var vars = <JS.MetaLetVariable, JS.Expression>{}; | 4153 var vars = <JS.MetaLetVariable, JS.Expression>{}; |
| 4153 var l = _visit(_bindValue(vars, 'l', target)); | 4154 var l = _visit(_bindValue(vars, 'l', target)); |
| 4154 return new JS.MetaLet(vars, [ | 4155 return new JS.MetaLet(vars, [ |
| 4155 js.call('(#[dart._extensionType]) ? #[dartx[#]] : #.#', | 4156 js.call('(#[dart._extensionType]) ? #[dartx[#]] : #.#', |
| 4156 [l, l, name, l, name]) | 4157 [l, l, name, l, name]) |
| 4157 ]); | 4158 ]); |
| 4158 } | 4159 } |
| 4159 return js.call('dart.dload(#, #)', [_visit(target), name]); | 4160 return js.call('dart.dload(#, #)', [_visit(target), name]); |
| 4160 } | 4161 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4192 | 4193 |
| 4193 /// Emits a generic send, like an operator method. | 4194 /// Emits a generic send, like an operator method. |
| 4194 /// | 4195 /// |
| 4195 /// **Please note** this function does not support method invocation syntax | 4196 /// **Please note** this function does not support method invocation syntax |
| 4196 /// `obj.name(args)` because that could be a getter followed by a call. | 4197 /// `obj.name(args)` because that could be a getter followed by a call. |
| 4197 /// See [visitMethodInvocation]. | 4198 /// See [visitMethodInvocation]. |
| 4198 JS.Expression _emitSend( | 4199 JS.Expression _emitSend( |
| 4199 Expression target, String name, List<Expression> args) { | 4200 Expression target, String name, List<Expression> args) { |
| 4200 var type = getStaticType(target); | 4201 var type = getStaticType(target); |
| 4201 var memberName = _emitMemberName(name, unary: args.isEmpty, type: type); | 4202 var memberName = _emitMemberName(name, unary: args.isEmpty, type: type); |
| 4202 if (DynamicInvoke.get(target)) { | 4203 if (isDynamicInvoke(target)) { |
| 4203 if (_inWhitelistCode(target)) { | 4204 if (_inWhitelistCode(target)) { |
| 4204 var vars = <JS.MetaLetVariable, JS.Expression>{}; | 4205 var vars = <JS.MetaLetVariable, JS.Expression>{}; |
| 4205 var l = _visit(_bindValue(vars, 'l', target)); | 4206 var l = _visit(_bindValue(vars, 'l', target)); |
| 4206 return new JS.MetaLet(vars, [ | 4207 return new JS.MetaLet(vars, [ |
| 4207 js.call('(#[(#[dart._extensionType]) ? dartx[#] : #])(#)', | 4208 js.call('(#[(#[dart._extensionType]) ? dartx[#] : #])(#)', |
| 4208 [l, l, memberName, memberName, _visitList(args)]) | 4209 [l, l, memberName, memberName, _visitList(args)]) |
| 4209 ]); | 4210 ]); |
| 4210 } | 4211 } |
| 4211 // dynamic dispatch | 4212 // dynamic dispatch |
| 4212 var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name]; | 4213 var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name]; |
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4986 } | 4987 } |
| 4987 | 4988 |
| 4988 bool isLibraryPrefix(Expression node) => | 4989 bool isLibraryPrefix(Expression node) => |
| 4989 node is SimpleIdentifier && node.staticElement is PrefixElement; | 4990 node is SimpleIdentifier && node.staticElement is PrefixElement; |
| 4990 | 4991 |
| 4991 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 4992 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
| 4992 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 4993 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
| 4993 | 4994 |
| 4994 bool _isDartRuntime(LibraryElement l) => | 4995 bool _isDartRuntime(LibraryElement l) => |
| 4995 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 4996 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
| OLD | NEW |