Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: lib/src/compiler/code_generator.dart

Issue 2249233002: fix #626, add AMD module format and make it default (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: merged Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/runtime/run.js ('k') | lib/src/compiler/command.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ast_properties.dart' 24 import 'package:analyzer/src/task/strong/ast_properties.dart'
25 show isDynamicInvoke, setIsDynamicInvoke; 25 show isDynamicInvoke, setIsDynamicInvoke;
26 import 'package:source_maps/source_maps.dart';
27 import 'package:path/path.dart' show separator; 26 import 'package:path/path.dart' show separator;
28 27
29 import '../closure/closure_annotator.dart' show ClosureAnnotator; 28 import '../closure/closure_annotator.dart' show ClosureAnnotator;
30 import '../js_ast/js_ast.dart' as JS; 29 import '../js_ast/js_ast.dart' as JS;
31 import '../js_ast/js_ast.dart' show js; 30 import '../js_ast/js_ast.dart' show js;
32 import 'ast_builder.dart' show AstBuilder; 31 import 'ast_builder.dart' show AstBuilder;
33 import 'compiler.dart' 32 import 'compiler.dart'
34 show BuildUnit, CompilerOptions, JSModuleFile, ModuleFormat; 33 show BuildUnit, CompilerOptions, JSModuleFile;
35 import 'element_helpers.dart'; 34 import 'element_helpers.dart';
36 import 'element_loader.dart' show ElementLoader; 35 import 'element_loader.dart' show ElementLoader;
37 import 'extension_types.dart' show ExtensionTypeSet; 36 import 'extension_types.dart' show ExtensionTypeSet;
38 import 'js_field_storage.dart' show checkForPropertyOverride, getSuperclasses; 37 import 'js_field_storage.dart' show checkForPropertyOverride, getSuperclasses;
39 import 'js_interop.dart'; 38 import 'js_interop.dart';
40 import 'js_metalet.dart' as JS; 39 import 'js_metalet.dart' as JS;
41 import 'js_names.dart' as JS; 40 import 'js_names.dart' as JS;
42 import 'js_typeref_codegen.dart' show JsTypeRefCodegen; 41 import 'js_typeref_codegen.dart' show JsTypeRefCodegen;
43 import 'module_builder.dart' 42 import 'module_builder.dart' show pathToJSIdentifier;
44 show LegacyModuleBuilder, NodeModuleBuilder, pathToJSIdentifier;
45 import 'nullable_type_inference.dart' show NullableTypeInference; 43 import 'nullable_type_inference.dart' show NullableTypeInference;
46 import 'reify_coercions.dart' show CoercionReifier; 44 import 'reify_coercions.dart' show CoercionReifier;
47 import 'side_effect_analysis.dart' show ConstFieldVisitor, isStateless; 45 import 'side_effect_analysis.dart' show ConstFieldVisitor, isStateless;
48 import 'source_map_printer.dart' show SourceMapPrintingContext;
49 import 'type_utilities.dart'; 46 import 'type_utilities.dart';
50 47
51 class CodeGenerator extends GeneralizingAstVisitor 48 class CodeGenerator extends GeneralizingAstVisitor
52 with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference { 49 with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference {
53 final AnalysisContext context; 50 final AnalysisContext context;
54 final CompilerOptions options; 51 final CompilerOptions options;
55 final rules = new StrongTypeSystemImpl(); 52 final rules = new StrongTypeSystemImpl();
56 53
57 /// The set of libraries we are currently compiling, and the temporaries used 54 /// The set of libraries we are currently compiling, and the temporaries used
58 /// to refer to them. 55 /// to refer to them.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 /// Takes the metadata for the build unit, as well as resolved trees and 163 /// Takes the metadata for the build unit, as well as resolved trees and
167 /// errors, and computes the output module code and optionally the source map. 164 /// errors, and computes the output module code and optionally the source map.
168 JSModuleFile compile(BuildUnit unit, List<CompilationUnit> compilationUnits, 165 JSModuleFile compile(BuildUnit unit, List<CompilationUnit> compilationUnits,
169 List<String> errors) { 166 List<String> errors) {
170 _buildUnit = unit; 167 _buildUnit = unit;
171 _libraryRoot = _buildUnit.libraryRoot; 168 _libraryRoot = _buildUnit.libraryRoot;
172 if (!_libraryRoot.endsWith(separator)) { 169 if (!_libraryRoot.endsWith(separator)) {
173 _libraryRoot = '$_libraryRoot${separator}'; 170 _libraryRoot = '$_libraryRoot${separator}';
174 } 171 }
175 172
176 var jsTree = _emitModule(compilationUnits); 173 var module = _emitModule(compilationUnits);
177 var codeAndSourceMap = _writeJSText(unit, jsTree); 174 var dartApiSummary = _summarizeModule(compilationUnits);
178 175
179 List<int> summary; 176 return new JSModuleFile(unit.name, errors, options, module, dartApiSummary);
180 if (options.summarizeApi) {
181 var assembler = new PackageBundleAssembler();
182 compilationUnits
183 .map((u) => u.element.library)
184 .toSet()
185 .forEach(assembler.serializeLibraryElement);
186 summary = assembler.assemble().toBuffer();
187 }
188
189 return new JSModuleFile(
190 unit.name, errors, codeAndSourceMap.e0, codeAndSourceMap.e1, summary);
191 } 177 }
192 178
193 Tuple2<String, Map> _writeJSText(BuildUnit unit, JS.Program jsTree) { 179 List<int> _summarizeModule(List<CompilationUnit> compilationUnits) {
194 var opts = new JS.JavaScriptPrintingOptions( 180 if (!options.summarizeApi) return null;
195 emitTypes: options.closure,
196 allowKeywordsInProperties: true,
197 allowSingleLineIfStatements: true);
198 JS.SimpleJavaScriptPrintingContext printer;
199 SourceMapBuilder sourceMap;
200 if (options.sourceMap) {
201 var sourceMapContext = new SourceMapPrintingContext();
202 sourceMap = sourceMapContext.sourceMap;
203 printer = sourceMapContext;
204 } else {
205 printer = new JS.SimpleJavaScriptPrintingContext();
206 }
207 181
208 jsTree.accept(new JS.Printer(opts, printer, 182 var assembler = new PackageBundleAssembler();
209 localNamer: new JS.TemporaryNamer(jsTree))); 183 compilationUnits
210 184 .map((u) => u.element.library)
211 if (options.sourceMap && options.sourceMapComment) { 185 .toSet()
212 printer.emit('\n//# sourceMappingURL=${unit.name}.js.map\n'); 186 .forEach(assembler.serializeLibraryElement);
213 } 187 return assembler.assemble().toBuffer();
214
215 return new Tuple2(printer.getText(), sourceMap?.build(unit.name + '.js'));
216 } 188 }
217 189
218 JS.Program _emitModule(List<CompilationUnit> compilationUnits) { 190 JS.Program _emitModule(List<CompilationUnit> compilationUnits) {
219 if (_moduleItems.isNotEmpty) { 191 if (_moduleItems.isNotEmpty) {
220 throw new StateError('Can only call emitModule once.'); 192 throw new StateError('Can only call emitModule once.');
221 } 193 }
222 194
223 // Transform the AST to make coercions explicit. 195 // Transform the AST to make coercions explicit.
224 compilationUnits = CoercionReifier.reify(compilationUnits); 196 compilationUnits = CoercionReifier.reify(compilationUnits);
225 197
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 _finishImports(items); 249 _finishImports(items);
278 250
279 // Discharge the type table cache variables and 251 // Discharge the type table cache variables and
280 // hoisted definitions. 252 // hoisted definitions.
281 items.addAll(_typeTable.discharge()); 253 items.addAll(_typeTable.discharge());
282 254
283 // Add the module's code (produced by visiting compilation units, above) 255 // Add the module's code (produced by visiting compilation units, above)
284 _copyAndFlattenBlocks(items, _moduleItems); 256 _copyAndFlattenBlocks(items, _moduleItems);
285 257
286 // Build the module. 258 // Build the module.
287 var module = new JS.Program(items, name: _buildUnit.name); 259 return new JS.Program(items, name: _buildUnit.name);
288
289 // Optional: lower module format. Otherwise just return it.
290 switch (options.moduleFormat) {
291 case ModuleFormat.legacy:
292 return new LegacyModuleBuilder().build(module);
293 case ModuleFormat.node:
294 return new NodeModuleBuilder().build(module);
295 case ModuleFormat.es6:
296 return module;
297 }
298 return null; // unreachable. It is here to suppress a bogus Analyzer message
299 } 260 }
300 261
301 List<String> _getJSName(Element e) { 262 List<String> _getJSName(Element e) {
302 if (findAnnotation(e.library, isPublicJSAnnotation) == null) { 263 if (findAnnotation(e.library, isPublicJSAnnotation) == null) {
303 return null; 264 return null;
304 } 265 }
305 266
306 var libraryJSName = getAnnotationName(e.library, isPublicJSAnnotation); 267 var libraryJSName = getAnnotationName(e.library, isPublicJSAnnotation);
307 var libraryPrefix = <String>[]; 268 var libraryPrefix = <String>[];
308 if (libraryJSName != null && libraryJSName.isNotEmpty) { 269 if (libraryJSName != null && libraryJSName.isNotEmpty) {
(...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 var property = new JS.Property(memberName, type); 1704 var property = new JS.Property(memberName, type);
1744 tCtors.add(property); 1705 tCtors.add(property);
1745 } 1706 }
1746 1707
1747 JS.Property build(String name, List<JS.Property> elements) { 1708 JS.Property build(String name, List<JS.Property> elements) {
1748 var o = 1709 var o =
1749 new JS.ObjectInitializer(elements, multiline: elements.length > 1); 1710 new JS.ObjectInitializer(elements, multiline: elements.length > 1);
1750 var e = js.call('() => #', o); 1711 var e = js.call('() => #', o);
1751 return new JS.Property(_propertyName(name), e); 1712 return new JS.Property(_propertyName(name), e);
1752 } 1713 }
1714
1753 var sigFields = <JS.Property>[]; 1715 var sigFields = <JS.Property>[];
1754 if (!tCtors.isEmpty) sigFields.add(build('constructors', tCtors)); 1716 if (!tCtors.isEmpty) sigFields.add(build('constructors', tCtors));
1755 if (!tMethods.isEmpty) sigFields.add(build('methods', tMethods)); 1717 if (!tMethods.isEmpty) sigFields.add(build('methods', tMethods));
1756 if (!tStatics.isEmpty) { 1718 if (!tStatics.isEmpty) {
1757 assert(!sNames.isEmpty); 1719 assert(!sNames.isEmpty);
1758 var aNames = new JS.Property( 1720 var aNames = new JS.Property(
1759 _propertyName('names'), new JS.ArrayInitializer(sNames)); 1721 _propertyName('names'), new JS.ArrayInitializer(sNames));
1760 sigFields.add(build('statics', tStatics)); 1722 sigFields.add(build('statics', tStatics));
1761 sigFields.add(aNames); 1723 sigFields.add(aNames);
1762 } 1724 }
(...skipping 1492 matching lines...) Expand 10 before | Expand all | Expand 10 after
3255 var element = node.methodName.staticElement; 3217 var element = node.methodName.staticElement;
3256 bool isStatic = element is ExecutableElement && element.isStatic; 3218 bool isStatic = element is ExecutableElement && element.isStatic;
3257 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); 3219 var memberName = _emitMemberName(name, type: type, isStatic: isStatic);
3258 3220
3259 JS.Expression jsTarget = _visit(target); 3221 JS.Expression jsTarget = _visit(target);
3260 if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) { 3222 if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) {
3261 if (_inWhitelistCode(target)) { 3223 if (_inWhitelistCode(target)) {
3262 var vars = <JS.MetaLetVariable, JS.Expression>{}; 3224 var vars = <JS.MetaLetVariable, JS.Expression>{};
3263 var l = _visit(_bindValue(vars, 'l', target)); 3225 var l = _visit(_bindValue(vars, 'l', target));
3264 jsTarget = new JS.MetaLet(vars, [ 3226 jsTarget = new JS.MetaLet(vars, [
3265 js.call('(#[(#[dart._extensionType]) ? dartx[#] : #])', 3227 js.call('(#[(#[dart._extensionType]) ? dartx[#] : #])', [
3266 [l, l, memberName, memberName,]) 3228 l,
3229 l,
3230 memberName,
3231 memberName,
3232 ])
3267 ]); 3233 ]);
3268 if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs); 3234 if (typeArgs != null) jsTarget = new JS.Call(jsTarget, typeArgs);
3269 return new JS.Call(jsTarget, args); 3235 return new JS.Call(jsTarget, args);
3270 } 3236 }
3271 if (typeArgs != null) { 3237 if (typeArgs != null) {
3272 return js.call('dart.dgsend(#, #, #, #)', 3238 return js.call('dart.dgsend(#, #, #, #)',
3273 [jsTarget, new JS.ArrayInitializer(typeArgs), memberName, args]); 3239 [jsTarget, new JS.ArrayInitializer(typeArgs), memberName, args]);
3274 } else { 3240 } else {
3275 return js.call('dart.dsend(#, #, #)', [jsTarget, memberName, args]); 3241 return js.call('dart.dsend(#, #, #)', [jsTarget, memberName, args]);
3276 } 3242 }
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
3799 if (name != null) { 3765 if (name != null) {
3800 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name)); 3766 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name));
3801 } 3767 }
3802 } else { 3768 } else {
3803 ctor = _emitConstructorName(element, type, name); 3769 ctor = _emitConstructorName(element, type, name);
3804 isFactory = element.isFactory; 3770 isFactory = element.isFactory;
3805 } 3771 }
3806 var args = _visit(argumentList) as List<JS.Expression>; 3772 var args = _visit(argumentList) as List<JS.Expression>;
3807 return isFactory ? new JS.Call(ctor, args) : new JS.New(ctor, args); 3773 return isFactory ? new JS.Call(ctor, args) : new JS.New(ctor, args);
3808 } 3774 }
3775
3809 if (element != null && _isObjectLiteral(element.enclosingElement)) { 3776 if (element != null && _isObjectLiteral(element.enclosingElement)) {
3810 return _emitObjectLiteral(argumentList); 3777 return _emitObjectLiteral(argumentList);
3811 } 3778 }
3812 if (isConst) return _emitConst(emitNew); 3779 if (isConst) return _emitConst(emitNew);
3813 return emitNew(); 3780 return emitNew();
3814 } 3781 }
3815 3782
3816 bool _isObjectLiteral(ClassElement classElem) { 3783 bool _isObjectLiteral(ClassElement classElem) {
3817 return findAnnotation(classElem, isPublicJSAnnotation) != null && 3784 return findAnnotation(classElem, isPublicJSAnnotation) != null &&
3818 findAnnotation(classElem, isJSAnonymousAnnotation) != null; 3785 findAnnotation(classElem, isJSAnonymousAnnotation) != null;
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
4040 } 4007 }
4041 int finishIdentifier(SimpleIdentifier identifier) { 4008 int finishIdentifier(SimpleIdentifier identifier) {
4042 Element staticElement = identifier.staticElement; 4009 Element staticElement = identifier.staticElement;
4043 if (staticElement is PropertyAccessorElement && staticElement.isGetter) { 4010 if (staticElement is PropertyAccessorElement && staticElement.isGetter) {
4044 PropertyInducingElement variable = staticElement.variable; 4011 PropertyInducingElement variable = staticElement.variable;
4045 int value = variable?.constantValue?.toIntValue(); 4012 int value = variable?.constantValue?.toIntValue();
4046 if (value != null && value >= low && value <= high) return value; 4013 if (value != null && value >= low && value <= high) return value;
4047 } 4014 }
4048 return null; 4015 return null;
4049 } 4016 }
4017
4050 if (expr is SimpleIdentifier) { 4018 if (expr is SimpleIdentifier) {
4051 return finishIdentifier(expr); 4019 return finishIdentifier(expr);
4052 } else if (expr is PrefixedIdentifier && !expr.isDeferred) { 4020 } else if (expr is PrefixedIdentifier && !expr.isDeferred) {
4053 return finishIdentifier(expr.identifier); 4021 return finishIdentifier(expr.identifier);
4054 } 4022 }
4055 return null; 4023 return null;
4056 } 4024 }
4057 4025
4058 bool _isDefinitelyNonNegative(Expression expr) { 4026 bool _isDefinitelyNonNegative(Expression expr) {
4059 expr = expr.unParenthesized; 4027 expr = expr.unParenthesized;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4127 } 4095 }
4128 return MAX; 4096 return MAX;
4129 default: 4097 default:
4130 return MAX; 4098 return MAX;
4131 } 4099 }
4132 } 4100 }
4133 int value = _asIntInRange(expr, 0, 0x7fffffff); 4101 int value = _asIntInRange(expr, 0, 0x7fffffff);
4134 if (value != null) return value.bitLength; 4102 if (value != null) return value.bitLength;
4135 return MAX; 4103 return MAX;
4136 } 4104 }
4105
4137 return bitWidth(expr, 0) < 32; 4106 return bitWidth(expr, 0) < 32;
4138 } 4107 }
4139 4108
4140 /// If the type [t] is [int] or [double], or a type parameter 4109 /// If the type [t] is [int] or [double], or a type parameter
4141 /// bounded by [int], [double] or [num] returns [num]. 4110 /// bounded by [int], [double] or [num] returns [num].
4142 /// Otherwise returns [t]. 4111 /// Otherwise returns [t].
4143 DartType _canonicalizeNumTypes(DartType t) { 4112 DartType _canonicalizeNumTypes(DartType t) {
4144 var numType = types.numType; 4113 var numType = types.numType;
4145 if (rules.isSubtypeOf(t, numType)) return numType; 4114 if (rules.isSubtypeOf(t, numType)) return numType;
4146 return t; 4115 return t;
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
4917 visitNullLiteral(NullLiteral node) => new JS.LiteralNull(); 4886 visitNullLiteral(NullLiteral node) => new JS.LiteralNull();
4918 4887
4919 @override 4888 @override
4920 visitSymbolLiteral(SymbolLiteral node) { 4889 visitSymbolLiteral(SymbolLiteral node) {
4921 JS.Expression emitSymbol() { 4890 JS.Expression emitSymbol() {
4922 // TODO(vsm): When we canonicalize, we need to treat private symbols 4891 // TODO(vsm): When we canonicalize, we need to treat private symbols
4923 // correctly. 4892 // correctly.
4924 var name = js.string(node.components.join('.'), "'"); 4893 var name = js.string(node.components.join('.'), "'");
4925 return js.call('#.new(#)', [_emitType(types.symbolType), name]); 4894 return js.call('#.new(#)', [_emitType(types.symbolType), name]);
4926 } 4895 }
4896
4927 return _emitConst(emitSymbol); 4897 return _emitConst(emitSymbol);
4928 } 4898 }
4929 4899
4930 @override 4900 @override
4931 visitListLiteral(ListLiteral node) { 4901 visitListLiteral(ListLiteral node) {
4932 var isConst = node.constKeyword != null; 4902 var isConst = node.constKeyword != null;
4933 JS.Expression emitList() { 4903 JS.Expression emitList() {
4934 JS.Expression list = new JS.ArrayInitializer( 4904 JS.Expression list = new JS.ArrayInitializer(
4935 _visitList(node.elements) as List<JS.Expression>); 4905 _visitList(node.elements) as List<JS.Expression>);
4936 ParameterizedType type = node.staticType; 4906 ParameterizedType type = node.staticType;
4937 var elementType = type.typeArguments.single; 4907 var elementType = type.typeArguments.single;
4938 // TODO(jmesserly): analyzer will usually infer `List<Object>` because 4908 // TODO(jmesserly): analyzer will usually infer `List<Object>` because
4939 // that is the least upper bound of the element types. So we rarely 4909 // that is the least upper bound of the element types. So we rarely
4940 // generate a plain `List<dynamic>` anymore. 4910 // generate a plain `List<dynamic>` anymore.
4941 if (!elementType.isDynamic || isConst) { 4911 if (!elementType.isDynamic || isConst) {
4942 // dart.list helper internally depends on _interceptors.JSArray. 4912 // dart.list helper internally depends on _interceptors.JSArray.
4943 _declareBeforeUse(_jsArray); 4913 _declareBeforeUse(_jsArray);
4944 if (isConst) { 4914 if (isConst) {
4945 var typeRep = _emitType(elementType); 4915 var typeRep = _emitType(elementType);
4946 list = js.call('dart.constList(#, #)', [list, typeRep]); 4916 list = js.call('dart.constList(#, #)', [list, typeRep]);
4947 } else { 4917 } else {
4948 // Call `new JSArray<E>.of(list)` 4918 // Call `new JSArray<E>.of(list)`
4949 var jsArrayType = _jsArray.type.instantiate(type.typeArguments); 4919 var jsArrayType = _jsArray.type.instantiate(type.typeArguments);
4950 list = js.call('#.of(#)', [_emitType(jsArrayType), list]); 4920 list = js.call('#.of(#)', [_emitType(jsArrayType), list]);
4951 } 4921 }
4952 } 4922 }
4953 return list; 4923 return list;
4954 } 4924 }
4925
4955 if (isConst) return _cacheConst(emitList); 4926 if (isConst) return _cacheConst(emitList);
4956 return emitList(); 4927 return emitList();
4957 } 4928 }
4958 4929
4959 @override 4930 @override
4960 visitMapLiteral(MapLiteral node) { 4931 visitMapLiteral(MapLiteral node) {
4961 // TODO(jmesserly): we can likely make these faster. 4932 // TODO(jmesserly): we can likely make these faster.
4962 JS.Expression emitMap() { 4933 JS.Expression emitMap() {
4963 var entries = node.entries; 4934 var entries = node.entries;
4964 var mapArguments = null; 4935 var mapArguments = null;
(...skipping 18 matching lines...) Expand all
4983 values.add(_visit(e.value)); 4954 values.add(_visit(e.value));
4984 } 4955 }
4985 mapArguments = new JS.ArrayInitializer(values); 4956 mapArguments = new JS.ArrayInitializer(values);
4986 } 4957 }
4987 var types = <JS.Expression>[]; 4958 var types = <JS.Expression>[];
4988 if (reifyTypeArgs) { 4959 if (reifyTypeArgs) {
4989 types.addAll(typeArgs.map((e) => _emitType(e))); 4960 types.addAll(typeArgs.map((e) => _emitType(e)));
4990 } 4961 }
4991 return js.call('dart.map(#, #)', [mapArguments, types]); 4962 return js.call('dart.map(#, #)', [mapArguments, types]);
4992 } 4963 }
4964
4993 if (node.constKeyword != null) return _emitConst(emitMap); 4965 if (node.constKeyword != null) return _emitConst(emitMap);
4994 return emitMap(); 4966 return emitMap();
4995 } 4967 }
4996 4968
4997 @override 4969 @override
4998 JS.LiteralString visitSimpleStringLiteral(SimpleStringLiteral node) => 4970 JS.LiteralString visitSimpleStringLiteral(SimpleStringLiteral node) =>
4999 js.escapedString(node.value, node.isSingleQuoted ? "'" : '"'); 4971 js.escapedString(node.value, node.isSingleQuoted ? "'" : '"');
5000 4972
5001 @override 4973 @override
5002 JS.Expression visitAdjacentStrings(AdjacentStrings node) => 4974 JS.Expression visitAdjacentStrings(AdjacentStrings node) =>
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
5059 5031
5060 /// Generates an expression for a boolean conversion context (if, while, &&, 5032 /// Generates an expression for a boolean conversion context (if, while, &&,
5061 /// etc.), where conversions and null checks are implemented via `dart.test` 5033 /// etc.), where conversions and null checks are implemented via `dart.test`
5062 /// to give a more helpful message. 5034 /// to give a more helpful message.
5063 // TODO(sra): When nullablility is available earlier, it would be cleaner to 5035 // TODO(sra): When nullablility is available earlier, it would be cleaner to
5064 // build an input AST where the boolean conversion is a single AST node. 5036 // build an input AST where the boolean conversion is a single AST node.
5065 JS.Expression _visitTest(Expression node) { 5037 JS.Expression _visitTest(Expression node) {
5066 JS.Expression finish(JS.Expression result) { 5038 JS.Expression finish(JS.Expression result) {
5067 return annotate(result, node); 5039 return annotate(result, node);
5068 } 5040 }
5041
5069 if (node is PrefixExpression && node.operator.lexeme == '!') { 5042 if (node is PrefixExpression && node.operator.lexeme == '!') {
5070 return finish(js.call('!#', _visitTest(node.operand))); 5043 return finish(js.call('!#', _visitTest(node.operand)));
5071 } 5044 }
5072 if (node is ParenthesizedExpression) { 5045 if (node is ParenthesizedExpression) {
5073 return finish(_visitTest(node.expression)); 5046 return finish(_visitTest(node.expression));
5074 } 5047 }
5075 if (node is BinaryExpression) { 5048 if (node is BinaryExpression) {
5076 JS.Expression shortCircuit(String code) { 5049 JS.Expression shortCircuit(String code) {
5077 return finish(js.call(code, 5050 return finish(js.call(code,
5078 [_visitTest(node.leftOperand), _visitTest(node.rightOperand)])); 5051 [_visitTest(node.leftOperand), _visitTest(node.rightOperand)]));
5079 } 5052 }
5053
5080 var op = node.operator.type.lexeme; 5054 var op = node.operator.type.lexeme;
5081 if (op == '&&') return shortCircuit('# && #'); 5055 if (op == '&&') return shortCircuit('# && #');
5082 if (op == '||') return shortCircuit('# || #'); 5056 if (op == '||') return shortCircuit('# || #');
5083 } 5057 }
5084 if (isReifiedCoercion(node)) { 5058 if (isReifiedCoercion(node)) {
5085 AsExpression asNode = node; 5059 AsExpression asNode = node;
5086 assert(asNode.staticType == types.boolType); 5060 assert(asNode.staticType == types.boolType);
5087 return js.call('dart.test(#)', _visit(asNode.expression)); 5061 return js.call('dart.test(#)', _visit(asNode.expression));
5088 } 5062 }
5089 JS.Expression result = _visit(node); 5063 JS.Expression result = _visit(node);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
5134 /// They generate code like: 5108 /// They generate code like:
5135 /// 5109 ///
5136 /// x['+'](y) 5110 /// x['+'](y)
5137 /// 5111 ///
5138 /// There are three exceptions: [], []= and unary -. 5112 /// There are three exceptions: [], []= and unary -.
5139 /// The indexing operators we use `get` and `set` instead: 5113 /// The indexing operators we use `get` and `set` instead:
5140 /// 5114 ///
5141 /// x.get('hi') 5115 /// x.get('hi')
5142 /// x.set('hi', 123) 5116 /// x.set('hi', 123)
5143 /// 5117 ///
5144 /// This follows the same pattern as EcmaScript 6 Map: 5118 /// This follows the same pattern as ECMAScript 6 Map:
5145 /// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_ Objects/Map> 5119 /// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_ Objects/Map>
5146 /// 5120 ///
5147 /// Unary minus looks like: `x['unary-']()`. Note that [unary] must be passed 5121 /// Unary minus looks like: `x['unary-']()`. Note that [unary] must be passed
5148 /// for this transformation to happen, otherwise binary minus is assumed. 5122 /// for this transformation to happen, otherwise binary minus is assumed.
5149 /// 5123 ///
5150 /// Equality is a bit special, it is generated via the Dart `equals` runtime 5124 /// Equality is a bit special, it is generated via the Dart `equals` runtime
5151 /// helper, that checks for null. The user defined method is called '=='. 5125 /// helper, that checks for null. The user defined method is called '=='.
5152 /// 5126 ///
5153 JS.Expression _emitMemberName(String name, 5127 JS.Expression _emitMemberName(String name,
5154 {DartType type, 5128 {DartType type,
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
5287 // TODO(leafp): The above only handles the case where the return type 5261 // TODO(leafp): The above only handles the case where the return type
5288 // is exactly Future/Stream/Iterable. Handle the subtype case. 5262 // is exactly Future/Stream/Iterable. Handle the subtype case.
5289 return DynamicTypeImpl.instance; 5263 return DynamicTypeImpl.instance;
5290 } 5264 }
5291 } 5265 }
5292 5266
5293 /// Maps whitelisted files to a list of whitelisted methods 5267 /// Maps whitelisted files to a list of whitelisted methods
5294 /// within the file. 5268 /// within the file.
5295 /// 5269 ///
5296 /// If the value is null, the entire file is whitelisted. 5270 /// If the value is null, the entire file is whitelisted.
5271 ///
5272 // TODO(jmesserly): why is this here, and what can we do to remove it?
5273 //
5274 // Hard coded lists are completely unnecessary -- if a feature is needed,
5275 // metadata, type system features, or command line options are the right way
5276 // to express it.
5277 //
5278 // As it is this is completely unsound and unmaintainable.
5297 static Map<String, List<String>> _uncheckedWhitelist = { 5279 static Map<String, List<String>> _uncheckedWhitelist = {
5298 'dom_renderer.dart': ['moveNodesAfterSibling',], 5280 'dom_renderer.dart': ['moveNodesAfterSibling'],
5299 'template_ref.dart': ['createEmbeddedView'], 5281 'template_ref.dart': ['createEmbeddedView'],
5300 'ng_class.dart': ['_applyIterableChanges'], 5282 'ng_class.dart': ['_applyIterableChanges'],
5301 'ng_for.dart': ['_bulkRemove', '_bulkInsert'], 5283 'ng_for.dart': ['_bulkRemove', '_bulkInsert'],
5302 'view_container_ref.dart': ['createEmbeddedView'], 5284 'view_container_ref.dart': ['createEmbeddedView'],
5303 'default_iterable_differ.dart': null, 5285 'default_iterable_differ.dart': null,
5304 }; 5286 };
5305 5287
5306 static Set<String> _uncheckedWhitelistCalls = new Set() 5288 static Set<String> _uncheckedWhitelistCalls = new Set()
5307 ..add('ng_zone_impl.dart') 5289 ..add('ng_zone_impl.dart')
5308 ..add('stack_zone_specification.dart') 5290 ..add('stack_zone_specification.dart')
(...skipping 19 matching lines...) Expand all
5328 } 5310 }
5329 5311
5330 // Dynamic calls are less risky so there is no need to whitelist at the 5312 // Dynamic calls are less risky so there is no need to whitelist at the
5331 // method level. 5313 // method level.
5332 if (isCall && _uncheckedWhitelistCalls.contains(filename)) return true; 5314 if (isCall && _uncheckedWhitelistCalls.contains(filename)) return true;
5333 5315
5334 return path.endsWith(".template.dart"); 5316 return path.endsWith(".template.dart");
5335 } 5317 }
5336 } 5318 }
5337 5319
5338 /// Choose a canonical name from the library element. 5320 /// Choose a canonical name from the [library] element.
5321 ///
5339 /// This never uses the library's name (the identifier in the `library` 5322 /// This never uses the library's name (the identifier in the `library`
5340 /// declaration) as it doesn't have any meaningful rules enforced. 5323 /// declaration) as it doesn't have any meaningful rules enforced.
5341 String jsLibraryName(String libraryRoot, LibraryElement library) { 5324 String jsLibraryName(String libraryRoot, LibraryElement library) {
5342 var uri = library.source.uri; 5325 var uri = library.source.uri;
5343 if (uri.scheme == 'dart') { 5326 if (uri.scheme == 'dart') {
5344 return uri.path; 5327 return uri.path;
5345 } 5328 }
5346 // TODO(vsm): This is not necessarily unique if '__' appears in a file name. 5329 // TODO(vsm): This is not necessarily unique if '__' appears in a file name.
5347 var separator = '__'; 5330 var separator = '__';
5348 String qualifiedPath; 5331 String qualifiedPath;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5385 } 5368 }
5386 5369
5387 bool isLibraryPrefix(Expression node) => 5370 bool isLibraryPrefix(Expression node) =>
5388 node is SimpleIdentifier && node.staticElement is PrefixElement; 5371 node is SimpleIdentifier && node.staticElement is PrefixElement;
5389 5372
5390 LibraryElement _getLibrary(AnalysisContext c, String uri) => 5373 LibraryElement _getLibrary(AnalysisContext c, String uri) =>
5391 c.computeLibraryElement(c.sourceFactory.forUri(uri)); 5374 c.computeLibraryElement(c.sourceFactory.forUri(uri));
5392 5375
5393 bool _isDartRuntime(LibraryElement l) => 5376 bool _isDartRuntime(LibraryElement l) =>
5394 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; 5377 l.isInSdk && l.source.uri.toString() == 'dart:_runtime';
OLDNEW
« no previous file with comments | « lib/runtime/run.js ('k') | lib/src/compiler/command.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698