OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 compiler; | 5 library compiler; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection' show SplayTreeMap; | 8 import 'dart:collection' show SplayTreeMap; |
9 import 'dart:json' as json; | 9 import 'dart:json' as json; |
| 10 |
10 import 'package:analyzer_experimental/src/generated/ast.dart' show Directive, Ur
iBasedDirective; | 11 import 'package:analyzer_experimental/src/generated/ast.dart' show Directive, Ur
iBasedDirective; |
11 import 'package:csslib/visitor.dart' show StyleSheet, treeToDebugString; | 12 import 'package:csslib/visitor.dart' show StyleSheet, treeToDebugString; |
12 import 'package:html5lib/dom.dart'; | 13 import 'package:html5lib/dom.dart'; |
13 import 'package:html5lib/parser.dart'; | 14 import 'package:html5lib/parser.dart'; |
| 15 import 'package:observe/transform.dart' show transformObservables; |
14 import 'package:source_maps/span.dart' show Span; | 16 import 'package:source_maps/span.dart' show Span; |
| 17 import 'package:source_maps/refactor.dart' show TextEditTransaction; |
| 18 import 'package:source_maps/printer.dart'; |
15 | 19 |
16 import 'analyzer.dart'; | 20 import 'analyzer.dart'; |
17 import 'code_printer.dart'; | 21 import 'css_analyzer.dart' show analyzeCss, findUrlsImported, |
| 22 findImportsInStyleSheet, parseCss; |
| 23 import 'css_emitters.dart' show rewriteCssUris, |
| 24 emitComponentStyleSheet, emitOriginalCss, emitStyleSheet; |
18 import 'dart_parser.dart'; | 25 import 'dart_parser.dart'; |
19 import 'emitters.dart'; | 26 import 'emitters.dart'; |
20 import 'file_system.dart'; | 27 import 'file_system.dart'; |
21 import 'files.dart'; | 28 import 'files.dart'; |
22 import 'html_css_fixup.dart'; | |
23 import 'info.dart'; | 29 import 'info.dart'; |
24 import 'messages.dart'; | 30 import 'messages.dart'; |
25 import 'observable_transform.dart' show transformObservables; | |
26 import 'compiler_options.dart'; | 31 import 'compiler_options.dart'; |
27 import 'paths.dart'; | 32 import 'paths.dart'; |
28 import 'refactor.dart'; | |
29 import 'utils.dart'; | 33 import 'utils.dart'; |
30 | 34 |
31 /** | 35 /** |
32 * Parses an HTML file [contents] and returns a DOM-like tree. | 36 * Parses an HTML file [contents] and returns a DOM-like tree. |
33 * Note that [contents] will be a [String] if coming from a browser-based | 37 * Note that [contents] will be a [String] if coming from a browser-based |
34 * [FileSystem], or it will be a [List<int>] if running on the command line. | 38 * [FileSystem], or it will be a [List<int>] if running on the command line. |
35 * | 39 * |
36 * Adds emitted error/warning to [messages], if [messages] is supplied. | 40 * Adds emitted error/warning to [messages], if [messages] is supplied. |
37 */ | 41 */ |
38 Document parseHtml(contents, String sourcePath, Messages messages) { | 42 Document parseHtml(contents, String sourcePath, Messages messages) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 bool isEntryPoint = _processed.length == 1; | 149 bool isEntryPoint = _processed.length == 1; |
146 | 150 |
147 files.add(file); | 151 files.add(file); |
148 | 152 |
149 var fileInfo = _time('Analyzed definitions', inputUrl.url, () { | 153 var fileInfo = _time('Analyzed definitions', inputUrl.url, () { |
150 return analyzeDefinitions(global, inputUrl, file.document, | 154 return analyzeDefinitions(global, inputUrl, file.document, |
151 _pathMapper.packageRoot, _messages, isEntryPoint: isEntryPoint); | 155 _pathMapper.packageRoot, _messages, isEntryPoint: isEntryPoint); |
152 }); | 156 }); |
153 info[inputUrl.resolvedPath] = fileInfo; | 157 info[inputUrl.resolvedPath] = fileInfo; |
154 | 158 |
155 if (isEntryPoint && options.hasCssReset) { | 159 if (isEntryPoint && _resetCssFile != null) { |
156 _processed.add(_resetCssFile); | 160 _processed.add(_resetCssFile); |
157 _tasks.add(_parseCssFile(new UrlInfo(_resetCssFile, _resetCssFile, | 161 _tasks.add(_parseCssFile(new UrlInfo(_resetCssFile, _resetCssFile, |
158 null))); | 162 null))); |
159 } | 163 } |
160 | 164 |
161 _setOutputFilenames(fileInfo); | 165 _setOutputFilenames(fileInfo); |
162 _processImports(fileInfo); | 166 _processImports(fileInfo); |
163 | 167 |
164 // Load component files referenced by [file]. | 168 // Load component files referenced by [file]. |
165 for (var link in fileInfo.componentLinks) { | 169 for (var link in fileInfo.componentLinks) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 .then((code) { | 269 .then((code) { |
266 if (code == null) return; | 270 if (code == null) return; |
267 var file = new SourceFile(filePath, type: SourceFile.DART); | 271 var file = new SourceFile(filePath, type: SourceFile.DART); |
268 file.code = code; | 272 file.code = code; |
269 _processDartFile(inputUrl, file); | 273 _processDartFile(inputUrl, file); |
270 }); | 274 }); |
271 } | 275 } |
272 | 276 |
273 /** Parse a stylesheet file. */ | 277 /** Parse a stylesheet file. */ |
274 Future _parseCssFile(UrlInfo inputUrl) { | 278 Future _parseCssFile(UrlInfo inputUrl) { |
275 if (!options.processCss || | 279 if (!options.emulateScopedCss || |
276 !_pathMapper.checkInputPath(inputUrl, _messages)) { | 280 !_pathMapper.checkInputPath(inputUrl, _messages)) { |
277 return new Future<SourceFile>.value(null); | 281 return new Future<SourceFile>.value(null); |
278 } | 282 } |
279 var filePath = inputUrl.resolvedPath; | 283 var filePath = inputUrl.resolvedPath; |
280 return fileSystem.readText(filePath) | 284 return fileSystem.readText(filePath) |
281 .catchError((e) => _readError(e, inputUrl, isWarning: true)) | 285 .catchError((e) => _readError(e, inputUrl, isWarning: true)) |
282 .then((code) { | 286 .then((code) { |
283 if (code == null) return; | 287 if (code == null) return; |
284 var file = new SourceFile(filePath, type: SourceFile.STYLESHEET); | 288 var file = new SourceFile(filePath, type: SourceFile.STYLESHEET); |
285 file.code = code; | 289 file.code = code; |
(...skipping 16 matching lines...) Expand all Loading... |
302 } | 306 } |
303 | 307 |
304 void _processDartFile(UrlInfo inputUrl, SourceFile dartFile) { | 308 void _processDartFile(UrlInfo inputUrl, SourceFile dartFile) { |
305 if (dartFile == null) return; | 309 if (dartFile == null) return; |
306 | 310 |
307 files.add(dartFile); | 311 files.add(dartFile); |
308 | 312 |
309 var resolvedPath = inputUrl.resolvedPath; | 313 var resolvedPath = inputUrl.resolvedPath; |
310 var fileInfo = new FileInfo(inputUrl); | 314 var fileInfo = new FileInfo(inputUrl); |
311 info[resolvedPath] = fileInfo; | 315 info[resolvedPath] = fileInfo; |
312 fileInfo.inlinedCode = | 316 fileInfo.inlinedCode = parseDartCode(resolvedPath, dartFile.code); |
313 parseDartCode(resolvedPath, dartFile.code, _messages); | |
314 fileInfo.outputFilename = | 317 fileInfo.outputFilename = |
315 _pathMapper.mangle(path.basename(resolvedPath), '.dart', false); | 318 _pathMapper.mangle(path.basename(resolvedPath), '.dart', false); |
316 | 319 |
317 _processImports(fileInfo); | 320 _processImports(fileInfo); |
318 } | 321 } |
319 | 322 |
320 void _processImports(LibraryInfo library) { | 323 void _processImports(LibraryInfo library) { |
321 if (library.userCode == null) return; | 324 if (library.userCode == null) return; |
322 | 325 |
323 for (var directive in library.userCode.directives) { | 326 for (var directive in library.userCode.directives) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 /** | 381 /** |
379 * Transform Dart source code. | 382 * Transform Dart source code. |
380 * Currently, the only transformation is [transformObservables]. | 383 * Currently, the only transformation is [transformObservables]. |
381 * Calls _emitModifiedDartFiles to write the transformed files. | 384 * Calls _emitModifiedDartFiles to write the transformed files. |
382 */ | 385 */ |
383 void _transformDart() { | 386 void _transformDart() { |
384 var libraries = _findAllDartLibraries(); | 387 var libraries = _findAllDartLibraries(); |
385 | 388 |
386 var transformed = []; | 389 var transformed = []; |
387 for (var lib in libraries) { | 390 for (var lib in libraries) { |
388 var transaction = transformObservables(lib.userCode, _messages); | 391 var userCode = lib.userCode; |
| 392 var transaction = transformObservables(userCode.compilationUnit, |
| 393 userCode.sourceFile, userCode.code, _messages); |
389 if (transaction != null) { | 394 if (transaction != null) { |
390 _edits[lib.userCode] = transaction; | 395 _edits[lib.userCode] = transaction; |
391 if (transaction.hasEdits) { | 396 if (transaction.hasEdits) { |
392 transformed.add(lib); | 397 transformed.add(lib); |
393 } else if (lib.htmlFile != null) { | 398 } else if (lib.htmlFile != null) { |
394 // All web components will be transformed too. Track that. | 399 // All web components will be transformed too. Track that. |
395 transformed.add(lib); | 400 transformed.add(lib); |
396 } | 401 } |
397 } | 402 } |
398 } | 403 } |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 } | 539 } |
535 } | 540 } |
536 } | 541 } |
537 | 542 |
538 /** Run the analyzer on every input html file. */ | 543 /** Run the analyzer on every input html file. */ |
539 void _analyze() { | 544 void _analyze() { |
540 var uniqueIds = new IntIterator(); | 545 var uniqueIds = new IntIterator(); |
541 for (var file in files) { | 546 for (var file in files) { |
542 if (file.isHtml) { | 547 if (file.isHtml) { |
543 _time('Analyzed contents', file.path, () => | 548 _time('Analyzed contents', file.path, () => |
544 analyzeFile(file, info, uniqueIds, global, _messages)); | 549 analyzeFile(file, info, uniqueIds, global, _messages, |
| 550 options.emulateScopedCss)); |
545 } | 551 } |
546 } | 552 } |
547 } | 553 } |
548 | 554 |
549 /** Emit the generated code corresponding to each input file. */ | 555 /** Emit the generated code corresponding to each input file. */ |
550 void _emit() { | 556 void _emit() { |
551 for (var file in files) { | 557 for (var file in files) { |
552 if (file.isDart || file.isStyleSheet) continue; | 558 if (file.isDart || file.isStyleSheet) continue; |
553 _time('Codegen', file.path, () { | 559 _time('Codegen', file.path, () { |
554 var fileInfo = info[file.path]; | 560 var fileInfo = info[file.path]; |
555 fixupHtmlCss(fileInfo, options); | |
556 _emitComponents(fileInfo); | 561 _emitComponents(fileInfo); |
557 }); | 562 }); |
558 } | 563 } |
559 | 564 |
560 var entryPoint = files[0]; | 565 var entryPoint = files[0]; |
561 assert(info[entryPoint.path].isEntryPoint); | 566 assert(info[entryPoint.path].isEntryPoint); |
562 _emitMainDart(entryPoint); | 567 _emitMainDart(entryPoint); |
563 _emitMainHtml(entryPoint); | 568 _emitMainHtml(entryPoint); |
564 | 569 |
565 assert(_unqiueOutputs()); | 570 assert(_unqiueOutputs()); |
(...skipping 10 matching lines...) Expand all Loading... |
576 } | 581 } |
577 return true; | 582 return true; |
578 } | 583 } |
579 | 584 |
580 /** Emit the main .dart file. */ | 585 /** Emit the main .dart file. */ |
581 void _emitMainDart(SourceFile file) { | 586 void _emitMainDart(SourceFile file) { |
582 var fileInfo = info[file.path]; | 587 var fileInfo = info[file.path]; |
583 | 588 |
584 var codeInfo = fileInfo.userCode; | 589 var codeInfo = fileInfo.userCode; |
585 if (codeInfo != null) { | 590 if (codeInfo != null) { |
586 var printer = new CodePrinter(0); | 591 var printer = new NestedPrinter(0); |
587 if (codeInfo.libraryName == null) { | 592 if (codeInfo.libraryName == null) { |
588 printer.addLine('library ${fileInfo.libraryName};'); | 593 printer.addLine('library ${fileInfo.libraryName};'); |
589 } | 594 } |
590 printer.add(codeInfo.code); | 595 printer.add(codeInfo.code); |
591 _emitFileAndSourceMaps(fileInfo, printer, fileInfo.dartCodeUrl); | 596 _emitFileAndSourceMaps(fileInfo, printer, fileInfo.dartCodeUrl); |
592 } | 597 } |
593 } | 598 } |
594 | 599 |
595 // TODO(jmesserly): refactor this out of Compiler. | 600 // TODO(jmesserly): refactor this out of Compiler. |
596 /** Generate an html file with the (trimmed down) main html page. */ | 601 /** Generate an html file with the (trimmed down) main html page. */ |
(...skipping 23 matching lines...) Expand all Loading... |
620 document.outerHtml, source: file.path)); | 625 document.outerHtml, source: file.path)); |
621 } | 626 } |
622 | 627 |
623 // TODO(jmesserly): refactor this and other CSS related transforms out of | 628 // TODO(jmesserly): refactor this and other CSS related transforms out of |
624 // Compiler. | 629 // Compiler. |
625 /** | 630 /** |
626 * Generate an CSS file for all style sheets (main and components). | 631 * Generate an CSS file for all style sheets (main and components). |
627 * Returns true if a file was generated, otherwise false. | 632 * Returns true if a file was generated, otherwise false. |
628 */ | 633 */ |
629 bool _emitAllCss() { | 634 bool _emitAllCss() { |
630 if (!options.processCss) return false; | 635 if (!options.emulateScopedCss) return false; |
631 | 636 |
632 var buff = new StringBuffer(); | 637 var buff = new StringBuffer(); |
633 | 638 |
634 // Emit all linked style sheet files first. | 639 // Emit all linked style sheet files first. |
635 for (var file in files) { | 640 for (var file in files) { |
636 var css = new StringBuffer(); | 641 var css = new StringBuffer(); |
637 var fileInfo = info[file.path]; | 642 var fileInfo = info[file.path]; |
638 if (file.isStyleSheet) { | 643 if (file.isStyleSheet) { |
639 for (var styleSheet in fileInfo.styleSheets) { | 644 for (var styleSheet in fileInfo.styleSheets) { |
640 // Translate any URIs in CSS. | 645 // Translate any URIs in CSS. |
641 var uriVisitor = new UriVisitor(_pathMapper, | 646 rewriteCssUris(_pathMapper, fileInfo.inputUrl.resolvedPath, |
642 fileInfo.inputUrl.resolvedPath, options.rewriteUrls); | 647 options.rewriteUrls, styleSheet); |
643 uriVisitor.visitTree(styleSheet); | |
644 | |
645 if (options.debugCss) { | |
646 print('\nCSS source: ${fileInfo.inputUrl.resolvedPath}'); | |
647 print('==========\n'); | |
648 print(treeToDebugString(styleSheet)); | |
649 } | |
650 | |
651 css.write( | 648 css.write( |
652 '/* Auto-generated from style sheet href = ${file.path} */\n' | 649 '/* Auto-generated from style sheet href = ${file.path} */\n' |
653 '/* DO NOT EDIT. */\n\n'); | 650 '/* DO NOT EDIT. */\n\n'); |
654 css.write(emitStyleSheet(styleSheet, fileInfo)); | 651 css.write(emitStyleSheet(styleSheet, fileInfo)); |
655 css.write('\n\n'); | 652 css.write('\n\n'); |
656 } | 653 } |
657 | 654 |
658 // Emit the linked style sheet in the output directory. | 655 // Emit the linked style sheet in the output directory. |
659 if (fileInfo.inputUrl.url != _resetCssFile) { | 656 if (fileInfo.inputUrl.url != _resetCssFile) { |
660 var outCss = _pathMapper.outputPath(fileInfo.inputUrl.resolvedPath, | 657 var outCss = _pathMapper.outputPath(fileInfo.inputUrl.resolvedPath, |
661 ''); | 658 ''); |
662 output.add(new OutputFile(outCss, css.toString())); | 659 output.add(new OutputFile(outCss, css.toString())); |
663 } | 660 } |
664 } | 661 } |
665 } | 662 } |
666 | 663 |
667 // Emit all CSS for each component (style scoped). | 664 // Emit all CSS for each component (style scoped). |
668 for (var file in files) { | 665 for (var file in files) { |
669 if (file.isHtml) { | 666 if (file.isHtml) { |
670 var fileInfo = info[file.path]; | 667 var fileInfo = info[file.path]; |
671 for (var component in fileInfo.declaredComponents) { | 668 for (var component in fileInfo.declaredComponents) { |
672 for (var styleSheet in component.styleSheets) { | 669 for (var styleSheet in component.styleSheets) { |
673 | |
674 // Translate any URIs in CSS. | 670 // Translate any URIs in CSS. |
675 var uriVisitor = new UriVisitor(_pathMapper, | 671 rewriteCssUris(_pathMapper, fileInfo.inputUrl.resolvedPath, |
676 fileInfo.inputUrl.resolvedPath, options.rewriteUrls); | 672 options.rewriteUrls, styleSheet); |
677 uriVisitor.visitTree(styleSheet); | |
678 | 673 |
679 if (buff.isEmpty) { | 674 if (buff.isEmpty) { |
680 buff.write( | 675 buff.write( |
681 '/* Auto-generated from components style tags. */\n' | 676 '/* Auto-generated from components style tags. */\n' |
682 '/* DO NOT EDIT. */\n\n'); | 677 '/* DO NOT EDIT. */\n\n'); |
683 } | 678 } |
684 buff.write( | 679 buff.write( |
685 '/* ==================================================== \n' | 680 '/* ==================================================== \n' |
686 ' Component ${component.tagName} stylesheet \n' | 681 ' Component ${component.tagName} stylesheet \n' |
687 ' ==================================================== */\n'); | 682 ' ==================================================== */\n'); |
688 | 683 |
689 var cssPolyfillKind = CssPolyfillKind.of(options, component); | |
690 var tagName = component.tagName; | 684 var tagName = component.tagName; |
691 if (!component.hasAuthorStyles) { | 685 if (!component.hasAuthorStyles) { |
692 if (_cssResetStyleSheet != null && !options.mangleCss) { | 686 if (_cssResetStyleSheet != null) { |
693 // If component doesn't have apply-author-styles then we need to | 687 // If component doesn't have apply-author-styles then we need to |
694 // reset the CSS the styles for the component (if css-reset file | 688 // reset the CSS the styles for the component (if css-reset file |
695 // option was passed). | 689 // option was passed). |
696 buff.write('\n/* Start CSS Reset */\n'); | 690 buff.write('\n/* Start CSS Reset */\n'); |
697 buff.write(emitComponentStyleSheet(_cssResetStyleSheet, tagName, | 691 var style; |
698 cssPolyfillKind)); | 692 if (options.emulateScopedCss) { |
| 693 style = emitComponentStyleSheet(_cssResetStyleSheet, tagName); |
| 694 } else { |
| 695 style = emitOriginalCss(_cssResetStyleSheet); |
| 696 } |
| 697 buff.write(style); |
699 buff.write('/* End CSS Reset */\n\n'); | 698 buff.write('/* End CSS Reset */\n\n'); |
700 } | 699 } |
701 } | 700 } |
702 buff.write(emitComponentStyleSheet(styleSheet, tagName, | 701 if (options.emulateScopedCss) { |
703 cssPolyfillKind)); | 702 buff.write(emitComponentStyleSheet(styleSheet, tagName)); |
| 703 } else { |
| 704 buff.write(emitOriginalCss(styleSheet)); |
| 705 } |
704 buff.write('\n\n'); | 706 buff.write('\n\n'); |
705 } | 707 } |
706 } | 708 } |
707 } | 709 } |
708 } | 710 } |
709 | 711 |
710 if (buff.isEmpty) return false; | 712 if (buff.isEmpty) return false; |
711 | 713 |
712 var cssPath = _pathMapper.outputPath(_mainPath, '.css', true); | 714 var cssPath = _pathMapper.outputPath(_mainPath, '.css', true); |
713 output.add(new OutputFile(cssPath, buff.toString())); | 715 output.add(new OutputFile(cssPath, buff.toString())); |
714 return true; | 716 return true; |
715 } | 717 } |
716 | 718 |
717 /** Emits the Dart code for all components in [fileInfo]. */ | 719 /** Emits the Dart code for all components in [fileInfo]. */ |
718 void _emitComponents(FileInfo fileInfo) { | 720 void _emitComponents(FileInfo fileInfo) { |
719 for (var component in fileInfo.declaredComponents) { | 721 for (var component in fileInfo.declaredComponents) { |
720 // TODO(terry): Handle one stylesheet per component see fixupHtmlCss. | 722 // TODO(terry): Handle more than one stylesheet per component |
721 if (component.styleSheets.length > 1 && options.processCss) { | 723 if (component.styleSheets.length > 1 && options.emulateScopedCss) { |
722 var span = component.externalFile != null | 724 var span = component.externalFile != null |
723 ? component.externalFile.sourceSpan : null; | 725 ? component.externalFile.sourceSpan : null; |
724 _messages.warning( | 726 _messages.warning( |
725 'Component has more than one stylesheet - first stylesheet used.', | 727 'Component has more than one stylesheet - first stylesheet used.', |
726 span); | 728 span); |
727 } | 729 } |
728 var printer = new WebComponentEmitter(fileInfo, _messages, | 730 var printer = emitPolymerElement( |
729 CssPolyfillKind.of(options, component)) | 731 component, _pathMapper, _edits[component.userCode], options); |
730 .run(component, _pathMapper, _edits[component.userCode]); | |
731 _emitFileAndSourceMaps(component, printer, component.externalFile); | 732 _emitFileAndSourceMaps(component, printer, component.externalFile); |
732 } | 733 } |
733 } | 734 } |
734 | 735 |
735 /** | 736 /** |
736 * Emits a file that was created using [CodePrinter] and it's corresponding | 737 * Emits a file that was created using [NestedPrinter] and it's corresponding |
737 * source map file. | 738 * source map file. |
738 */ | 739 */ |
739 void _emitFileAndSourceMaps( | 740 void _emitFileAndSourceMaps( |
740 LibraryInfo lib, CodePrinter printer, UrlInfo dartCodeUrl) { | 741 LibraryInfo lib, NestedPrinter printer, UrlInfo dartCodeUrl) { |
741 // Bail if we had an error generating the code for the file. | 742 // Bail if we had an error generating the code for the file. |
742 if (printer == null) return; | 743 if (printer == null) return; |
743 | 744 |
744 var libPath = _pathMapper.outputLibraryPath(lib); | 745 var libPath = _pathMapper.outputLibraryPath(lib); |
745 var dir = path.dirname(libPath); | 746 var dir = path.dirname(libPath); |
746 var filename = path.basename(libPath); | 747 var filename = path.basename(libPath); |
747 printer.add('\n//# sourceMappingURL=$filename.map'); | 748 printer.add('\n//# sourceMappingURL=$filename.map'); |
748 printer.build(libPath); | 749 printer.build(libPath); |
749 var sourcePath = dartCodeUrl != null ? dartCodeUrl.resolvedPath : null; | 750 var sourcePath = dartCodeUrl != null ? dartCodeUrl.resolvedPath : null; |
750 output.add(new OutputFile(libPath, printer.text, source: sourcePath)); | 751 output.add(new OutputFile(libPath, printer.text, source: sourcePath)); |
(...skipping 13 matching lines...) Expand all Loading... |
764 message.write(logMessage); | 765 message.write(logMessage); |
765 var filename = path.basename(filePath); | 766 var filename = path.basename(filePath); |
766 for (int i = (60 - logMessage.length - filename.length); i > 0 ; i--) { | 767 for (int i = (60 - logMessage.length - filename.length); i > 0 ; i--) { |
767 message.write(' '); | 768 message.write(' '); |
768 } | 769 } |
769 message.write(filename); | 770 message.write(filename); |
770 return time(message.toString(), callback, | 771 return time(message.toString(), callback, |
771 printTime: options.verbose || printTime); | 772 printTime: options.verbose || printTime); |
772 } | 773 } |
773 } | 774 } |
774 | |
OLD | NEW |