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

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: Address comments Created 4 years, 11 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/src/codegen/js_codegen.dart ('k') | lib/src/server/server.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_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(
22 JS.Program jsTree, String outputPath, String inputDir, Uri serverUri,
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 =
32 new SourceMapPrintingContext(printer, outDir, inputDir, serverUri);
31 } else { 33 } else {
32 context = new JS.SimpleJavaScriptPrintingContext(); 34 context = new JS.SimpleJavaScriptPrintingContext();
33 } 35 }
34 36
35 var opts = new JS.JavaScriptPrintingOptions( 37 var opts = new JS.JavaScriptPrintingOptions(
36 allowKeywordsInProperties: true, 38 allowKeywordsInProperties: true,
37 allowSingleLineIfStatements: true, 39 allowSingleLineIfStatements: true,
38 arrowFnBindThisWorkaround: arrowFnBindThisWorkaround); 40 arrowFnBindThisWorkaround: arrowFnBindThisWorkaround);
39 var jsNamer = new TemporaryNamer(jsTree); 41 var jsNamer = new TemporaryNamer(jsTree);
40 jsTree.accept(new JS.Printer(opts, context, localNamer: jsNamer)); 42 jsTree.accept(new JS.Printer(opts, context, localNamer: jsNamer));
(...skipping 25 matching lines...) Expand all
66 // TODO(jmesserly): should only do this if the input file was executable? 68 // TODO(jmesserly): should only do this if the input file was executable?
67 if (!Platform.isWindows) Process.runSync('chmod', ['+x', outputPath]); 69 if (!Platform.isWindows) Process.runSync('chmod', ['+x', outputPath]);
68 } 70 }
69 71
70 return computeHash(text); 72 return computeHash(text);
71 } 73 }
72 74
73 class SourceMapPrintingContext extends JS.JavaScriptPrintingContext { 75 class SourceMapPrintingContext extends JS.JavaScriptPrintingContext {
74 final srcmaps.Printer printer; 76 final srcmaps.Printer printer;
75 final String outputDir; 77 final String outputDir;
78 final String inputDir;
79
80 // TODO(vsm): we could abstract this out and have a generic Uri mapping
81 // instead of hardcoding a notion of a server uri.
82 final Uri serverUri;
76 83
77 CompilationUnit unit; 84 CompilationUnit unit;
78 Uri uri; 85 Uri uri;
79 86
80 SourceMapPrintingContext(this.printer, this.outputDir); 87 SourceMapPrintingContext(
88 this.printer, this.outputDir, this.inputDir, this.serverUri);
81 89
82 void emit(String string) { 90 void emit(String string) {
83 printer.add(string); 91 printer.add(string);
84 } 92 }
85 93
86 AstNode _currentTopLevelDeclaration; 94 AstNode _currentTopLevelDeclaration;
87 95
88 void enterNode(JS.Node jsNode) { 96 void enterNode(JS.Node jsNode) {
89 AstNode node = jsNode.sourceInformation; 97 AstNode node = jsNode.sourceInformation;
90 if (node == null || node.offset == -1) return; 98 if (node == null || node.offset == -1) return;
91 if (unit == null) { 99 if (unit == null) {
92 // This is a top-level declaration. Note: consecutive top-level 100 // This is a top-level declaration. Note: consecutive top-level
93 // declarations may come from different compilation units due to 101 // declarations may come from different compilation units due to
94 // parts. 102 // parts.
95 _currentTopLevelDeclaration = node; 103 _currentTopLevelDeclaration = node;
96 unit = node.getAncestor((n) => n is CompilationUnit); 104 unit = node.getAncestor((n) => n is CompilationUnit);
97 uri = _makeRelativeUri(unit.element.source.uri); 105 uri = _makeRelativeUri(unit.element.source.uri);
98 } 106 }
107 if (unit == null) return;
99 108
100 assert(unit != null); 109 assert(unit != null);
101 var loc = _location(node.offset); 110 var loc = _location(node.offset);
102 var name = _getIdentifier(node); 111 var name = _getIdentifier(node);
103 if (name != null) { 112 if (name != null) {
104 // TODO(jmesserly): mark only uses the beginning of the span, but 113 // TODO(jmesserly): mark only uses the beginning of the span, but
105 // we're required to pass this as a valid span. 114 // we're required to pass this as a valid span.
106 var end = _location(node.end); 115 var end = _location(node.end);
107 printer.mark(new SourceMapSpan(loc, end, name, isIdentifier: true)); 116 printer.mark(new SourceMapSpan(loc, end, name, isIdentifier: true));
108 } else { 117 } else {
109 printer.mark(loc); 118 printer.mark(loc);
110 } 119 }
111 } 120 }
112 121
113 SourceLocation _location(int offset) => 122 SourceLocation _location(int offset) =>
114 locationForOffset(unit.lineInfo, uri, offset); 123 locationForOffset(unit.lineInfo, uri, offset);
115 124
116 Uri _makeRelativeUri(Uri src) { 125 Uri _makeRelativeUri(Uri src) {
117 return new Uri(path: path.relative(src.path, from: outputDir)); 126 if (serverUri == null) {
127 return new Uri(path: path.relative(src.path, from: outputDir));
128 } else {
129 if (src.path.startsWith('/')) {
130 return serverUri.resolve(path.relative(src.path, from: inputDir));
131 } else {
132 return serverUri.resolve(path.join('packages', src.path));
133 }
134 }
118 } 135 }
119 136
120 void exitNode(JS.Node jsNode) { 137 void exitNode(JS.Node jsNode) {
121 AstNode node = jsNode.sourceInformation; 138 AstNode node = jsNode.sourceInformation;
122 if (unit == null || node == null || node.offset == -1) return; 139 if (unit == null || node == null || node.offset == -1) return;
123 140
124 // TODO(jmesserly): in many cases marking the end will be unnecessary. 141 // TODO(jmesserly): in many cases marking the end will be unnecessary.
125 printer.mark(_location(node.end)); 142 printer.mark(_location(node.end));
126 143
127 if (_currentTopLevelDeclaration == node) { 144 if (_currentTopLevelDeclaration == node) {
128 unit = null; 145 unit = null;
129 uri = null; 146 uri = null;
130 _currentTopLevelDeclaration == null; 147 _currentTopLevelDeclaration == null;
131 return; 148 return;
132 } 149 }
133 } 150 }
134 151
135 String _getIdentifier(AstNode node) { 152 String _getIdentifier(AstNode node) {
136 if (node is SimpleIdentifier) return node.name; 153 if (node is SimpleIdentifier) return node.name;
137 return null; 154 return null;
138 } 155 }
139 } 156 }
OLDNEW
« no previous file with comments | « lib/src/codegen/js_codegen.dart ('k') | lib/src/server/server.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698