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

Side by Side Diff: pkg/dev_compiler/web/stack_trace_mapper.dart

Issue 2747513003: Inline source maps as part of each script. (Closed)
Patch Set: Inline source maps as part of each script. Created 3 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 | « pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart ('k') | no next file » | 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 /// Standalone utility that manages loading source maps for all Dart scripts 5 /// Standalone utility that manages loading source maps for all Dart scripts
6 /// on the page compiled with DDC. 6 /// on the page compiled with DDC.
7 /// 7 ///
8 /// Example JavaScript usage: 8 /// Example JavaScript usage:
9 /// $dartStackTraceUtility.addLoadedListener(function() { 9 /// $dartStackTraceUtility.addLoadedListener(function() {
10 /// // All Dart source maps are now loaded. It is now safe to start your 10 /// // All Dart source maps are now loaded. It is now safe to start your
(...skipping 21 matching lines...) Expand all
32 import 'package:source_span/source_span.dart'; 32 import 'package:source_span/source_span.dart';
33 import 'package:stack_trace/stack_trace.dart'; 33 import 'package:stack_trace/stack_trace.dart';
34 34
35 typedef void ReadyCallback(); 35 typedef void ReadyCallback();
36 36
37 /// Global object DDC uses to see if a stack trace utility has been registered. 37 /// Global object DDC uses to see if a stack trace utility has been registered.
38 @JS(r'$dartStackTraceUtility') 38 @JS(r'$dartStackTraceUtility')
39 external set dartStackTraceUtility(DartStackTraceUtility value); 39 external set dartStackTraceUtility(DartStackTraceUtility value);
40 40
41 typedef String StackTraceMapper(String stackTrace); 41 typedef String StackTraceMapper(String stackTrace);
42 typedef dynamic LoadSourceMaps(List<String> scripts, ReadyCallback callback); 42 typedef String SourceMapProvider(String modulePath);
43 typedef String SetSourceMapProvider(SourceMapProvider provider);
43 44
44 @JS() 45 @JS()
45 @anonymous 46 @anonymous
46 class DartStackTraceUtility { 47 class DartStackTraceUtility {
47 external factory DartStackTraceUtility( 48 external factory DartStackTraceUtility(
48 {StackTraceMapper mapper, LoadSourceMaps loadSourceMaps}); 49 {StackTraceMapper mapper, SetSourceMapProvider setSourceMapProvider});
49 } 50 }
50 51
51 /// Source mapping that is waits to parse source maps until they match the uri 52 /// Source mapping that is waits to parse source maps until they match the uri
52 /// of a requested source map. 53 /// of a requested source map.
53 /// 54 ///
54 /// This improves startup performance compared to using MappingBundle directly. 55 /// This improves startup performance compared to using MappingBundle directly.
55 /// The unparsed data for the source maps must still be loaded before 56 /// The unparsed data for the source maps must still be loaded before
56 /// LazyMapping is used. 57 /// LazyMapping is used.
57 class LazyMapping extends Mapping { 58 class LazyMapping extends Mapping {
58 MappingBundle _bundle = new MappingBundle(); 59 MappingBundle _bundle = new MappingBundle();
60 SourceMapProvider _provider;
59 61
60 /// Map from url to unparsed source map. 62 LazyMapping(this._provider);
61 Map<String, String> _sourceMaps;
62
63 LazyMapping(this._sourceMaps) {}
64 63
65 List toJson() => _bundle.toJson(); 64 List toJson() => _bundle.toJson();
66 65
67 SourceMapSpan spanFor(int line, int column, 66 SourceMapSpan spanFor(int line, int column,
68 {Map<String, SourceFile> files, String uri}) { 67 {Map<String, SourceFile> files, String uri}) {
69 if (uri == null) { 68 if (uri == null) {
70 throw new ArgumentError.notNull('uri'); 69 throw new ArgumentError.notNull('uri');
71 } 70 }
72 var rawMap = _sourceMaps[uri];
73 71
74 if (rawMap != null && rawMap.isNotEmpty && !_bundle.containsMapping(uri)) { 72 if (!_bundle.containsMapping(uri)) {
75 SingleMapping mapping = parse(rawMap); 73 var rawMap = _provider(uri);
76 mapping 74 if (rawMap != null) {
77 ..targetUrl = uri 75 SingleMapping mapping = parse(rawMap);
78 ..sourceRoot = '${path.dirname(uri)}/'; 76 mapping
79 _bundle.addMapping(mapping); 77 ..targetUrl = uri
78 ..sourceRoot = '${path.dirname(uri)}/';
79 _bundle.addMapping(mapping);
80 }
80 } 81 }
81 82 var span = _bundle.spanFor(line, column, files: files, uri: uri);
82 return _bundle.spanFor(line, column, files: files, uri: uri); 83 // TODO(jacobr): we shouldn't have to filter out invalid sourceUrl entries
84 // here.
85 if (span == null || span.start.sourceUrl == null) return null;
86 var pathSegments = span.start.sourceUrl.pathSegments;
87 if (pathSegments.isNotEmpty && pathSegments.last == 'null') return null;
88 return span;
83 } 89 }
84 } 90 }
85 91
86 String _toSourceMapLocation(String url) { 92 String _toSourceMapLocation(String url) {
87 // The url may have cache busting query parameters which we need to maintain 93 // The url may have cache busting query parameters which we need to maintain
88 // in the source map url. 94 // in the source map url.
89 // For example: 95 // For example:
90 // http://localhost/foo.js?cachebusting=23419 96 // http://localhost/foo.js?cachebusting=23419
91 // Should get source map 97 // Should get source map
92 // http://localhost/foo.js.map?cachebusting=23419 98 // http://localhost/foo.js.map?cachebusting=23419
93 var uri = Uri.parse(url); 99 var uri = Uri.parse(url);
94 return uri.replace(path: '${uri.path}.map').toString(); 100 return uri.replace(path: '${uri.path}.map').toString();
95 } 101 }
96 102
97 /// Load a source map for the specified url.
98 ///
99 /// Returns a null string rather than reporting an error if the file cannot be
100 /// found as we don't want to throw errors if a few source maps are missing.
101 Future<String> loadSourceMap(String url) async {
102 try {
103 return await HttpRequest.getString(_toSourceMapLocation(url));
104 } catch (e) {
105 return null;
106 }
107 }
108
109 LazyMapping _mapping; 103 LazyMapping _mapping;
110 104
111 String mapper(String rawStackTrace) { 105 String mapper(String rawStackTrace) {
112 if (_mapping == null) { 106 if (_mapping == null) {
113 // This should not happen if the user has waited for the ReadyCallback 107 // This should not happen if the user has waited for the ReadyCallback
114 // to start the application. 108 // to start the application.
115 throw new StateError('Source maps are not done loading.'); 109 throw new StateError('Source maps are not done loading.');
116 } 110 }
117 return mapStackTrace(_mapping, new Trace.parse(rawStackTrace)).toString(); 111 return mapStackTrace(_mapping, new Trace.parse(rawStackTrace)).toString();
118 } 112 }
119 113
120 Future<Null> loadSourceMaps( 114 void setSourceMapProvider(SourceMapProvider provider) async {
121 List<String> scripts, ReadyCallback callback) async { 115 _mapping = new LazyMapping(provider);
122 List<Future<String>> sourceMapFutures =
123 scripts.map((script) => loadSourceMap(script)).toList();
124 List<String> sourceMaps = await Future.wait(sourceMapFutures);
125 _mapping = new LazyMapping(new Map.fromIterables(scripts, sourceMaps));
126 callback();
127 } 116 }
128 117
129 main() { 118 main() {
130 // Register with DDC. 119 // Register with DDC.
131 dartStackTraceUtility = new DartStackTraceUtility( 120 dartStackTraceUtility = new DartStackTraceUtility(
132 mapper: allowInterop(mapper), 121 mapper: allowInterop(mapper),
133 loadSourceMaps: allowInterop(loadSourceMaps)); 122 setSourceMapProvider: allowInterop(setSourceMapProvider));
134 } 123 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698