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

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

Issue 1530133003: Support source maps in server mode (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 5 years 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
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_printer; 5 library dev_compiler.src.codegen.js_printer;
6 6
7 import 'dart:convert' show JSON, JsonEncoder; 7 import 'dart:convert' show JSON, JsonEncoder;
8 import 'dart:io' show Directory, File, Platform, Process; 8 import 'dart:io' show Directory, File, Platform, Process;
9 9
10 import 'package:analyzer/src/generated/ast.dart'; 10 import 'package:analyzer/src/generated/ast.dart';
11 import 'package:path/path.dart' as path; 11 import 'package:path/path.dart' as path;
12 import 'package:source_maps/source_maps.dart' as srcmaps show Printer; 12 import 'package:source_maps/source_maps.dart' as srcmaps show Printer;
13 import 'package:source_maps/source_maps.dart' show SourceMapSpan; 13 import 'package:source_maps/source_maps.dart' show SourceMapSpan;
14 import 'package:source_span/source_span.dart' show SourceLocation; 14 import 'package:source_span/source_span.dart' show SourceLocation;
15 15
16 import '../js/js_ast.dart' as JS; 16 import '../js/js_ast.dart' as JS;
17 import '../utils.dart' show computeHash, locationForOffset; 17 import '../utils.dart' show computeHash, locationForOffset;
18 18
19 import 'js_names.dart' show TemporaryNamer; 19 import 'js_names.dart' show TemporaryNamer;
20 20
21 String writeJsLibrary(JS.Program jsTree, String outputPath, 21 String writeJsLibrary(JS.Program jsTree, String outputPath, String inputDir,
22 String serverUrl,
22 {bool emitSourceMaps: false, bool arrowFnBindThisWorkaround: false}) { 23 {bool emitSourceMaps: false, bool arrowFnBindThisWorkaround: false}) {
23 var outFilename = path.basename(outputPath); 24 var outFilename = path.basename(outputPath);
24 var outDir = path.dirname(outputPath); 25 var outDir = path.dirname(outputPath);
25 new Directory(outDir).createSync(recursive: true); 26 new Directory(outDir).createSync(recursive: true);
26 27
27 JS.JavaScriptPrintingContext context; 28 JS.JavaScriptPrintingContext context;
28 if (emitSourceMaps) { 29 if (emitSourceMaps) {
29 var printer = new srcmaps.Printer(outFilename); 30 var printer = new srcmaps.Printer(outFilename);
30 context = new SourceMapPrintingContext(printer, outDir); 31 context = new SourceMapPrintingContext(printer, outDir, inputDir, serverUrl) ;
31 } else { 32 } else {
32 context = new JS.SimpleJavaScriptPrintingContext(); 33 context = new JS.SimpleJavaScriptPrintingContext();
33 } 34 }
34 35
35 var opts = new JS.JavaScriptPrintingOptions( 36 var opts = new JS.JavaScriptPrintingOptions(
36 allowKeywordsInProperties: true, 37 allowKeywordsInProperties: true,
37 arrowFnBindThisWorkaround: arrowFnBindThisWorkaround); 38 arrowFnBindThisWorkaround: arrowFnBindThisWorkaround);
38 var jsNamer = new TemporaryNamer(jsTree); 39 var jsNamer = new TemporaryNamer(jsTree);
39 jsTree.accept(new JS.Printer(opts, context, localNamer: jsNamer)); 40 jsTree.accept(new JS.Printer(opts, context, localNamer: jsNamer));
40 41
(...skipping 24 matching lines...) Expand all
65 // TODO(jmesserly): should only do this if the input file was executable? 66 // TODO(jmesserly): should only do this if the input file was executable?
66 if (!Platform.isWindows) Process.runSync('chmod', ['+x', outputPath]); 67 if (!Platform.isWindows) Process.runSync('chmod', ['+x', outputPath]);
67 } 68 }
68 69
69 return computeHash(text); 70 return computeHash(text);
70 } 71 }
71 72
72 class SourceMapPrintingContext extends JS.JavaScriptPrintingContext { 73 class SourceMapPrintingContext extends JS.JavaScriptPrintingContext {
73 final srcmaps.Printer printer; 74 final srcmaps.Printer printer;
74 final String outputDir; 75 final String outputDir;
76 final String inputDir;
77 final String serverUrl;
75 78
76 CompilationUnit unit; 79 CompilationUnit unit;
77 Uri uri; 80 Uri uri;
78 81
79 SourceMapPrintingContext(this.printer, this.outputDir); 82 SourceMapPrintingContext(this.printer, this.outputDir, this.inputDir, this.ser verUrl);
Jennifer Messerly 2015/12/16 18:40:07 slight factoring thing, I wonder if we should pass
vsm 2016/01/07 21:22:03 added a todo
80 83
81 void emit(String string) { 84 void emit(String string) {
82 printer.add(string); 85 printer.add(string);
83 } 86 }
84 87
85 AstNode _currentTopLevelDeclaration; 88 AstNode _currentTopLevelDeclaration;
86 89
87 void enterNode(JS.Node jsNode) { 90 void enterNode(JS.Node jsNode) {
88 AstNode node = jsNode.sourceInformation; 91 AstNode node = jsNode.sourceInformation;
89 if (node == null || node.offset == -1) return; 92 if (node == null || node.offset == -1) return;
90 if (unit == null) { 93 if (unit == null) {
91 // This is a top-level declaration. Note: consecutive top-level 94 // This is a top-level declaration. Note: consecutive top-level
92 // declarations may come from different compilation units due to 95 // declarations may come from different compilation units due to
93 // parts. 96 // parts.
94 _currentTopLevelDeclaration = node; 97 _currentTopLevelDeclaration = node;
95 unit = node.getAncestor((n) => n is CompilationUnit); 98 unit = node.getAncestor((n) => n is CompilationUnit);
96 uri = _makeRelativeUri(unit.element.source.uri); 99 uri = _makeRelativeUri(unit.element.source.uri);
97 } 100 }
101 if (unit == null) return;
98 102
99 assert(unit != null); 103 assert(unit != null);
100 var loc = _location(node.offset); 104 var loc = _location(node.offset);
101 var name = _getIdentifier(node); 105 var name = _getIdentifier(node);
102 if (name != null) { 106 if (name != null) {
103 // TODO(jmesserly): mark only uses the beginning of the span, but 107 // TODO(jmesserly): mark only uses the beginning of the span, but
104 // we're required to pass this as a valid span. 108 // we're required to pass this as a valid span.
105 var end = _location(node.end); 109 var end = _location(node.end);
106 printer.mark(new SourceMapSpan(loc, end, name, isIdentifier: true)); 110 printer.mark(new SourceMapSpan(loc, end, name, isIdentifier: true));
107 } else { 111 } else {
108 printer.mark(loc); 112 printer.mark(loc);
109 } 113 }
110 } 114 }
111 115
112 SourceLocation _location(int offset) => 116 SourceLocation _location(int offset) =>
113 locationForOffset(unit.lineInfo, uri, offset); 117 locationForOffset(unit.lineInfo, uri, offset);
114 118
115 Uri _makeRelativeUri(Uri src) { 119 Uri _makeRelativeUri(Uri src) {
116 return new Uri(path: path.relative(src.path, from: outputDir)); 120 if (serverUrl == null) {
121 return new Uri(path: path.relative(src.path, from: outputDir));
122 } else {
123 if (src.path.startsWith('/')) {
124 return new Uri(path: serverUrl + path.relative(src.path, from: inputDir) );
Jennifer Messerly 2015/12/16 18:40:07 the name here's a little confusing, if this was a
vsm 2016/01/07 21:22:03 i think i was abusing the path argument to the Uri
125 } else {
126 return new Uri(path: serverUrl + 'packages/' + src.path);
127 }
128 }
117 } 129 }
118 130
119 void exitNode(JS.Node jsNode) { 131 void exitNode(JS.Node jsNode) {
120 AstNode node = jsNode.sourceInformation; 132 AstNode node = jsNode.sourceInformation;
121 if (unit == null || node == null || node.offset == -1) return; 133 if (unit == null || node == null || node.offset == -1) return;
122 134
123 // TODO(jmesserly): in many cases marking the end will be unnecessary. 135 // TODO(jmesserly): in many cases marking the end will be unnecessary.
124 printer.mark(_location(node.end)); 136 printer.mark(_location(node.end));
125 137
126 if (_currentTopLevelDeclaration == node) { 138 if (_currentTopLevelDeclaration == node) {
127 unit = null; 139 unit = null;
128 uri = null; 140 uri = null;
129 _currentTopLevelDeclaration == null; 141 _currentTopLevelDeclaration == null;
130 return; 142 return;
131 } 143 }
132 } 144 }
133 145
134 String _getIdentifier(AstNode node) { 146 String _getIdentifier(AstNode node) {
135 if (node is SimpleIdentifier) return node.name; 147 if (node is SimpleIdentifier) return node.name;
136 return null; 148 return null;
137 } 149 }
138 } 150 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698