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

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1011153002: js: fix core.Object, output order, static const fields (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 9 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/dart_runtime.js ('k') | lib/src/js/nodes.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 library dev_compiler.src.codegen.js_codegen; 5 library dev_compiler.src.codegen.js_codegen;
6 6
7 import 'dart:collection' show HashSet; 7 import 'dart:collection' show HashSet;
8 import 'dart:io' show Directory, File; 8 import 'dart:io' show Directory, File;
9 9
10 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 10 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
(...skipping 20 matching lines...) Expand all
31 import 'package:dev_compiler/src/utils.dart'; 31 import 'package:dev_compiler/src/utils.dart';
32 import 'code_generator.dart'; 32 import 'code_generator.dart';
33 33
34 // This must match the optional parameter name used in runtime.js 34 // This must match the optional parameter name used in runtime.js
35 const String _jsNamedParameterName = r'opt$'; 35 const String _jsNamedParameterName = r'opt$';
36 36
37 class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor { 37 class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
38 final LibraryInfo libraryInfo; 38 final LibraryInfo libraryInfo;
39 final TypeRules rules; 39 final TypeRules rules;
40 40
41 // TODO(jmesserly): this is needed because RestrictedTypeRules can send
42 // messages to CheckerReporter, for things like missing types.
43 // We should probably refactor so this can't happen, as codegen would be too
44 // late to be issuing these messages.
45 final CheckerReporter _checkerReporter;
46
41 /// The variable for the target of the current `..` cascade expression. 47 /// The variable for the target of the current `..` cascade expression.
42 SimpleIdentifier _cascadeTarget; 48 SimpleIdentifier _cascadeTarget;
43 /// The variable for the current catch clause 49 /// The variable for the current catch clause
44 String _catchParameter; 50 String _catchParameter;
45 51
46 ClassDeclaration currentClass; 52 ClassDeclaration currentClass;
47 ConstantEvaluator _constEvaluator; 53 ConstantEvaluator _constEvaluator;
48 54
49 final _exports = <String>[]; 55 final _exports = <String>[];
50 final _lazyFields = <VariableDeclaration>[]; 56 final _lazyFields = <VariableDeclaration>[];
51 final _properties = <FunctionDeclaration>[]; 57 final _properties = <FunctionDeclaration>[];
52 final _privateNames = new HashSet<String>(); 58 final _privateNames = new HashSet<String>();
53 final _pendingPrivateNames = <String>[]; 59 final _pendingPrivateNames = <String>[];
54 60
55 JSCodegenVisitor(LibraryInfo libraryInfo, TypeRules rules) 61 JSCodegenVisitor(this.libraryInfo, this.rules, this._checkerReporter);
56 : libraryInfo = libraryInfo,
57 rules = rules;
58 62
59 Element get currentLibrary => libraryInfo.library; 63 Element get currentLibrary => libraryInfo.library;
60 64
61 JS.Program generateLibrary( 65 JS.Program generateLibrary(Iterable<CompilationUnit> units) {
62 Iterable<CompilationUnit> units, CheckerReporter reporter) {
63 var body = <JS.Statement>[]; 66 var body = <JS.Statement>[];
64 for (var unit in units) { 67
65 // TODO(jmesserly): this is needed because RestrictedTypeRules can send 68 // Visit parts first, since the "part" declarations come before code
66 // messages to CheckerReporter, for things like missing types. 69 // in the main library's compilation unit.
vsm 2015/03/17 18:27:32 Is there a way to assert that the first is a libra
Jennifer Messerly 2015/03/17 18:58:45 Done. Introduced "LibraryUnit" type to assert the
67 // We should probably refactor so this can't happen. 70 for (var unit in units.skip(1)) {
68 var source = unit.element.source;
69 _constEvaluator = new ConstantEvaluator(source, rules.provider);
70 reporter.enterSource(source);
71 body.add(_visit(unit)); 71 body.add(_visit(unit));
72 reporter.leaveSource();
73 } 72 }
74 73
74 // Visit main library
75 body.add(_visit(units.first));
76
75 if (_exports.isNotEmpty) body.add(js.comment('Exports:')); 77 if (_exports.isNotEmpty) body.add(js.comment('Exports:'));
76 78
77 // TODO(jmesserly): make these immutable in JS? 79 // TODO(jmesserly): make these immutable in JS?
78 for (var name in _exports) { 80 for (var name in _exports) {
79 body.add(js.statement('$_EXPORTS.# = #;', [name, name])); 81 body.add(js.statement('$_EXPORTS.# = #;', [name, name]));
80 } 82 }
81 83
82 var name = jsLibraryName(libraryInfo.library); 84 var name = jsLibraryName(libraryInfo.library);
83 return new JS.Program([ 85 return new JS.Program([
84 js.statement('var #;', name), 86 js.statement('var #;', name),
85 js.statement("(function($_EXPORTS) { 'use strict'; #; })(# || (# = {}));", 87 js.statement("(function($_EXPORTS) { 'use strict'; #; })(# || (# = {}));",
86 [body, name, name]) 88 [body, name, name])
87 ]); 89 ]);
88 } 90 }
89 91
90 JS.Statement _initPrivateSymbol(String name) => 92 JS.Statement _initPrivateSymbol(String name) =>
91 js.statement('let # = Symbol(#);', [name, js.string(name, "'")]); 93 js.statement('let # = Symbol(#);', [name, js.string(name, "'")]);
92 94
93 @override 95 @override
94 JS.Statement visitCompilationUnit(CompilationUnit node) { 96 JS.Statement visitCompilationUnit(CompilationUnit node) {
97 var source = node.element.source;
98
99 _constEvaluator = new ConstantEvaluator(source, rules.provider);
100 _checkerReporter.enterSource(source);
101
95 // TODO(jmesserly): scriptTag, directives. 102 // TODO(jmesserly): scriptTag, directives.
96 var body = <JS.Statement>[]; 103 var body = <JS.Statement>[];
97 for (var child in node.declarations) { 104 for (var child in node.declarations) {
98 // Attempt to group adjacent fields/properties. 105 // Attempt to group adjacent fields/properties.
99 if (child is! TopLevelVariableDeclaration) _flushLazyFields(body); 106 if (child is! TopLevelVariableDeclaration) _flushLazyFields(body);
100 if (child is! FunctionDeclaration) _flushLibraryProperties(body); 107 if (child is! FunctionDeclaration) _flushLibraryProperties(body);
101 108
102 var code = _visit(child); 109 var code = _visit(child);
103 110
104 if (code != null) { 111 if (code != null) {
105 if (_pendingPrivateNames.isNotEmpty) { 112 if (_pendingPrivateNames.isNotEmpty) {
106 body.addAll(_pendingPrivateNames.map(_initPrivateSymbol)); 113 body.addAll(_pendingPrivateNames.map(_initPrivateSymbol));
107 _pendingPrivateNames.clear(); 114 _pendingPrivateNames.clear();
108 } 115 }
109 body.add(code); 116 body.add(code);
110 } 117 }
111 } 118 }
112 119
113 // Flush any unwritten fields/properties. 120 // Flush any unwritten fields/properties.
114 _flushLazyFields(body); 121 _flushLazyFields(body);
115 _flushLibraryProperties(body); 122 _flushLibraryProperties(body);
116 123
124 _checkerReporter.leaveSource();
125
117 assert(_pendingPrivateNames.isEmpty); 126 assert(_pendingPrivateNames.isEmpty);
118 return _statement(body); 127 return _statement(body);
119 } 128 }
120 129
121 bool isPublic(String name) => !name.startsWith('_'); 130 bool isPublic(String name) => !name.startsWith('_');
122 131
123 /// Conversions that we don't handle end up here. 132 /// Conversions that we don't handle end up here.
124 @override 133 @override
125 visitConversion(Conversion node) { 134 visitConversion(Conversion node) {
126 var from = node.baseType; 135 var from = node.baseType;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 'let # = dart.generic(function(#) { #; return #; });', [ 221 'let # = dart.generic(function(#) { #; return #; });', [
213 genericName, 222 genericName,
214 _visitList(node.typeParameters), 223 _visitList(node.typeParameters),
215 clazz, 224 clazz,
216 name 225 name
217 ]); 226 ]);
218 227
219 // TODO(jmesserly): we may not want this to be `dynamic` if the generic 228 // TODO(jmesserly): we may not want this to be `dynamic` if the generic
220 // has a lower bound, e.g. `<T extends SomeType>`. 229 // has a lower bound, e.g. `<T extends SomeType>`.
221 // https://github.com/dart-lang/dart-dev-compiler/issues/38 230 // https://github.com/dart-lang/dart-dev-compiler/issues/38
222 var typeArgs = new List.filled(node.typeParameters.length, 'dynamic'); 231 var typeArgs =
232 new List.filled(node.typeParameters.length, js.call('dart.dynamic'));
223 233
224 var dynInst = js.statement('let # = #(#);', [name, genericName, typeArgs]); 234 var dynInst = js.statement('let # = #(#);', [name, genericName, typeArgs]);
225 235
226 // TODO(jmesserly): is it worth exporting both names? Alternatively we could 236 // TODO(jmesserly): is it worth exporting both names? Alternatively we could
227 // put the generic type constructor on the <dynamic> instance. 237 // put the generic type constructor on the <dynamic> instance.
228 if (isPublic(name)) _exports.add('${name}\$'); 238 if (isPublic(name)) _exports.add('${name}\$');
229 return new JS.Block([genericDef, dynInst]); 239 return new JS.Block([genericDef, dynInst]);
230 } 240 }
231 241
232 @override 242 @override
233 JS.Statement visitClassDeclaration(ClassDeclaration node) { 243 JS.Statement visitClassDeclaration(ClassDeclaration node) {
234 currentClass = node; 244 currentClass = node;
235 245
246 // dart:core Object is a bit special.
247 var isObject = node.element.type.isObject;
248
236 var body = <JS.Statement>[]; 249 var body = <JS.Statement>[];
237 250
238 var name = node.name.name; 251 var name = node.name.name;
239 var ctors = <ConstructorDeclaration>[]; 252 var ctors = <ConstructorDeclaration>[];
240 var fields = <FieldDeclaration>[]; 253 var fields = <FieldDeclaration>[];
241 var staticFields = <FieldDeclaration>[]; 254 var staticFields = <FieldDeclaration>[];
242 for (var member in node.members) { 255 for (var member in node.members) {
243 if (member is ConstructorDeclaration) { 256 if (member is ConstructorDeclaration) {
244 ctors.add(member); 257 ctors.add(member);
245 } else if (member is FieldDeclaration) { 258 } else if (member is FieldDeclaration) {
246 (member.isStatic ? staticFields : fields).add(member); 259 (member.isStatic ? staticFields : fields).add(member);
247 } 260 }
248 } 261 }
249 262
250 var jsMethods = <JS.Method>[]; 263 var jsMethods = <JS.Method>[];
251 // Iff no constructor is specified for a class C, it implicitly has a 264 // Iff no constructor is specified for a class C, it implicitly has a
252 // default constructor `C() : super() {}`, unless C is class Object. 265 // default constructor `C() : super() {}`, unless C is class Object.
253 if (ctors.isEmpty && !node.element.type.isObject) { 266 if (ctors.isEmpty && !isObject) {
254 jsMethods.add(_emitImplicitConstructor(node, name, fields)); 267 jsMethods.add(_emitImplicitConstructor(node, name, fields));
255 } 268 }
256 269
257 for (var member in node.members) { 270 for (var member in node.members) {
258 if (member is ConstructorDeclaration) { 271 if (member is ConstructorDeclaration) {
259 jsMethods.add(_emitConstructor(member, name, fields)); 272 jsMethods.add(_emitConstructor(member, name, fields, isObject));
260 } else if (member is MethodDeclaration) { 273 } else if (member is MethodDeclaration) {
261 jsMethods.add(_visit(member)); 274 jsMethods.add(_visit(member));
262 } 275 }
263 } 276 }
264 277
265 // Support for adapting dart:core Iterator/Iterable to ES6 versions. 278 // Support for adapting dart:core Iterator/Iterable to ES6 versions.
266 // This lets them use for-of loops transparently. 279 // This lets them use for-of loops transparently.
267 // https://github.com/lukehoban/es6features#iterators--forof 280 // https://github.com/lukehoban/es6features#iterators--forof
268 if (node.element.library.isDartCore && node.element.name == 'Iterable') { 281 if (node.element.library.isDartCore && node.element.name == 'Iterable') {
269 JS.Fun body = js.call('''function() { 282 JS.Fun body = js.call('''function() {
270 var iterator = this.iterator; 283 var iterator = this.iterator;
271 return { 284 return {
272 next() { 285 next() {
273 var done = iterator.moveNext(); 286 var done = iterator.moveNext();
274 return { done: done, current: done ? void 0 : iterator.current }; 287 return { done: done, current: done ? void 0 : iterator.current };
275 } 288 }
276 }; 289 };
277 }'''); 290 }''');
278 jsMethods.add(new JS.Method(js.call('Symbol.iterator'), body)); 291 jsMethods.add(new JS.Method(js.call('Symbol.iterator'), body));
279 } 292 }
280 293
281 JS.Expression heritage; 294 JS.Expression heritage = null;
282 if (node.extendsClause != null) { 295 if (node.extendsClause != null) {
283 heritage = _visit(node.extendsClause.superclass); 296 heritage = _visit(node.extendsClause.superclass);
284 } else { 297 } else if (!isObject) {
285 heritage = js.call('dart.Object'); 298 heritage = _emitTypeName(rules.provider.objectType);
286 } 299 }
287 if (node.withClause != null) { 300 if (node.withClause != null) {
288 var mixins = _visitList(node.withClause.mixinTypes); 301 var mixins = _visitList(node.withClause.mixinTypes);
289 mixins.insert(0, heritage); 302 mixins.insert(0, heritage);
290 heritage = js.call('dart.mixin(#)', [mixins]); 303 heritage = js.call('dart.mixin(#)', [mixins]);
291 } 304 }
292 body.add(new JS.ClassDeclaration(new JS.ClassExpression( 305 body.add(new JS.ClassDeclaration(new JS.ClassExpression(
293 new JS.VariableDeclaration(name), heritage, 306 new JS.VariableDeclaration(name), heritage,
294 jsMethods.where((m) => m != null).toList(growable: false)))); 307 jsMethods.where((m) => m != null).toList(growable: false))));
295 308
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 if (fields.isEmpty) return null; 347 if (fields.isEmpty) return null;
335 348
336 dynamic body = _initializeFields(fields); 349 dynamic body = _initializeFields(fields);
337 var superCall = _superConstructorCall(node); 350 var superCall = _superConstructorCall(node);
338 if (superCall != null) body = [[body, superCall]]; 351 if (superCall != null) body = [[body, superCall]];
339 return new JS.Method( 352 return new JS.Method(
340 new JS.PropertyName(name), js.call('function() { #; }', body)); 353 new JS.PropertyName(name), js.call('function() { #; }', body));
341 } 354 }
342 355
343 JS.Method _emitConstructor(ConstructorDeclaration node, String className, 356 JS.Method _emitConstructor(ConstructorDeclaration node, String className,
344 List<FieldDeclaration> fields) { 357 List<FieldDeclaration> fields, bool isObject) {
345 if (_externalOrNative(node)) return null; 358 if (_externalOrNative(node)) return null;
346 359
347 var name = _constructorName(className, node.name); 360 var name = _constructorName(className, node.name);
348 361
362 // Code generation for Object's constructor.
363 JS.Block body;
364 if (isObject &&
365 node.body is EmptyFunctionBody &&
366 node.constKeyword != null &&
367 node.name == null) {
368 // Implements Dart constructor behavior. Because of V8 `super`
369 // [constructor restrictions]
370 // (https://code.google.com/p/v8/issues/detail?id=3330#c65)
371 // we cannot currently emit actual ES6 constructors with super calls.
372 // Instead we use the same trick as named constructors, and do them as
373 // instance methods that perform initialization.
374 // TODO(jmesserly): we'll need to rethink this once the ES6 spec and V8
375 // settles. See <https://github.com/dart-lang/dev_compiler/issues/51>.
376 // Performance of this pattern is likely to be bad.
377 body = js.statement('''{
378 // Get the class name for this instance.
379 var name = this.constructor.name;
380 // Call the default constructor.
381 var init = this[name];
382 var result = void 0;
383 if (init) result = init.apply(this, arguments);
384 return result === void 0 ? this : result;
385 }''');
386 } else {
387 body = _emitConstructorBody(node, fields);
388 }
389
349 // We generate constructors as initializer methods in the class; 390 // We generate constructors as initializer methods in the class;
350 // this allows use of `super` for instance methods/properties. 391 // this allows use of `super` for instance methods/properties.
351 // It also avoids V8 restrictions on `super` in default constructors. 392 // It also avoids V8 restrictions on `super` in default constructors.
352 return new JS.Method(new JS.PropertyName(name), 393 return new JS.Method(
353 new JS.Fun(_visit(node.parameters), _emitConstructorBody(node, fields))) 394 new JS.PropertyName(name), new JS.Fun(_visit(node.parameters), body))
354 ..sourceInformation = node; 395 ..sourceInformation = node;
355 } 396 }
356 397
357 String _constructorName(String className, SimpleIdentifier name) { 398 String _constructorName(String className, SimpleIdentifier name) {
358 if (name == null) return className; 399 if (name == null) return className;
359 return '$className\$${name.name}'; 400 return '$className\$${name.name}';
360 } 401 }
361 402
362 JS.Block _emitConstructorBody( 403 JS.Block _emitConstructorBody(
363 ConstructorDeclaration node, List<FieldDeclaration> fields) { 404 ConstructorDeclaration node, List<FieldDeclaration> fields) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 688
648 /// Writes a simple identifier. This can handle implicit `this` as well as 689 /// Writes a simple identifier. This can handle implicit `this` as well as
649 /// going through the qualified library name if necessary. 690 /// going through the qualified library name if necessary.
650 @override 691 @override
651 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { 692 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) {
652 var e = node.staticElement; 693 var e = node.staticElement;
653 if (e == null) { 694 if (e == null) {
654 return js.commentExpression( 695 return js.commentExpression(
655 'Unimplemented unknown name', new JS.VariableUse(node.name)); 696 'Unimplemented unknown name', new JS.VariableUse(node.name));
656 } 697 }
698
657 var name = node.name; 699 var name = node.name;
700 var variable = e is PropertyAccessorElement ? e.variable : e;
701
658 if (e.enclosingElement is CompilationUnitElement && 702 if (e.enclosingElement is CompilationUnitElement &&
659 (e.library != libraryInfo.library || _needsModuleGetter(e))) { 703 (e.library != libraryInfo.library ||
704 variable is TopLevelVariableElement && !variable.isConst)) {
660 return js.call('#.#', [_libraryName(e.library), name]); 705 return js.call('#.#', [_libraryName(e.library), name]);
661 } else if (currentClass != null && _needsImplicitThis(e)) { 706 } else if (currentClass != null && _needsImplicitThis(e)) {
662 return js.call('this.#', _jsMemberName(name)); 707 return js.call('this.#', _jsMemberName(name));
708 } else if (variable is ConstFieldElementImpl) {
709 var className = (variable.enclosingElement as ClassElement).name;
710 return js.call('#.#', [className, name]);
663 } else if (e is ParameterElement && e.isInitializingFormal) { 711 } else if (e is ParameterElement && e.isInitializingFormal) {
664 name = _fieldParameterName(name); 712 name = _fieldParameterName(name);
665 } 713 }
666 return new JS.VariableUse(name); 714 return new JS.VariableUse(name);
667 } 715 }
668 716
669 JS.Expression _emitTypeName(DartType type) { 717 JS.Expression _emitTypeName(DartType type) {
670 var name = type.name; 718 var name = type.name;
671 var lib = type.element.library; 719 var lib = type.element.library;
672 if (name == '') { 720 if (name == '') {
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 // ConstantEvaluator will not compute constants for non-const fields 1759 // ConstantEvaluator will not compute constants for non-const fields
1712 // at least for cases like `int x = 0;`, so run ConstantVisitor for those. 1760 // at least for cases like `int x = 0;`, so run ConstantVisitor for those.
1713 // TODO(jmesserly): ideally we'd only do this if we're sure it was skipped 1761 // TODO(jmesserly): ideally we'd only do this if we're sure it was skipped
1714 // by ConstantEvaluator. 1762 // by ConstantEvaluator.
1715 var initializer = field.initializer; 1763 var initializer = field.initializer;
1716 if (initializer == null) return null; 1764 if (initializer == null) return null;
1717 1765
1718 return _constEvaluator.evaluate(initializer); 1766 return _constEvaluator.evaluate(initializer);
1719 } 1767 }
1720 1768
1721 /// Returns true if [element] is a getter in JS, therefore needs
1722 /// `lib.topLevel` syntax instead of just `topLevel`.
1723 bool _needsModuleGetter(Element element) {
1724 if (element is PropertyAccessorElement) {
1725 element = (element as PropertyAccessorElement).variable;
1726 }
1727 return element is TopLevelVariableElement && !element.isConst;
1728 }
1729
1730 _visit(AstNode node) { 1769 _visit(AstNode node) {
1731 if (node == null) return null; 1770 if (node == null) return null;
1732 var result = node.accept(this); 1771 var result = node.accept(this);
1733 if (result is JS.Node) result.sourceInformation = node; 1772 if (result is JS.Node) result.sourceInformation = node;
1734 return result; 1773 return result;
1735 } 1774 }
1736 1775
1737 JS.Statement _visitOrEmpty(Statement node) { 1776 JS.Statement _visitOrEmpty(Statement node) {
1738 if (node == null) return new JS.EmptyStatement(); 1777 if (node == null) return new JS.EmptyStatement();
1739 return _visit(node); 1778 return _visit(node);
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1921 1960
1922 class JSGenerator extends CodeGenerator { 1961 class JSGenerator extends CodeGenerator {
1923 final JSCodeOptions options; 1962 final JSCodeOptions options;
1924 1963
1925 JSGenerator(String outDir, Uri root, TypeRules rules, this.options) 1964 JSGenerator(String outDir, Uri root, TypeRules rules, this.options)
1926 : super(outDir, root, rules); 1965 : super(outDir, root, rules);
1927 1966
1928 String generateLibrary(Iterable<CompilationUnit> units, LibraryInfo info, 1967 String generateLibrary(Iterable<CompilationUnit> units, LibraryInfo info,
1929 CheckerReporter reporter) { 1968 CheckerReporter reporter) {
1930 JS.Program jsTree = 1969 JS.Program jsTree =
1931 new JSCodegenVisitor(info, rules).generateLibrary(units, reporter); 1970 new JSCodegenVisitor(info, rules, reporter).generateLibrary(units);
1932 1971
1933 var outputPath = path.join(outDir, jsOutputPath(info, root)); 1972 var outputPath = path.join(outDir, jsOutputPath(info, root));
1934 new Directory(path.dirname(outputPath)).createSync(recursive: true); 1973 new Directory(path.dirname(outputPath)).createSync(recursive: true);
1935 1974
1936 if (options.emitSourceMaps) { 1975 if (options.emitSourceMaps) {
1937 var outFilename = path.basename(outputPath); 1976 var outFilename = path.basename(outputPath);
1938 var printer = new srcmaps.Printer(outFilename); 1977 var printer = new srcmaps.Printer(outFilename);
1939 _writeNode( 1978 _writeNode(
1940 new SourceMapPrintingContext(printer, path.dirname(outputPath)), 1979 new SourceMapPrintingContext(printer, path.dirname(outputPath)),
1941 jsTree); 1980 jsTree);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2039 2078
2040 // TODO(jmesserly): in many cases marking the end will be unncessary. 2079 // TODO(jmesserly): in many cases marking the end will be unncessary.
2041 printer.mark(_location(node.end)); 2080 printer.mark(_location(node.end));
2042 } 2081 }
2043 2082
2044 String _getIdentifier(AstNode node) { 2083 String _getIdentifier(AstNode node) {
2045 if (node is SimpleIdentifier) return node.name; 2084 if (node is SimpleIdentifier) return node.name;
2046 return null; 2085 return null;
2047 } 2086 }
2048 } 2087 }
OLDNEW
« no previous file with comments | « lib/runtime/dart_runtime.js ('k') | lib/src/js/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698