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 |