OLD | NEW |
---|---|
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 /* This file defines the module loader for the dart runtime. | 5 /* This file defines the module loader for the dart runtime. |
6 */ | 6 */ |
7 var dart_library; | 7 var dart_library; |
8 if (!dart_library) { | 8 if (!dart_library) { |
9 dart_library = | 9 dart_library = |
10 typeof module != "undefined" && module.exports || {}; | 10 typeof module != "undefined" && module.exports || {}; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 return module[name][p]; | 45 return module[name][p]; |
46 }, | 46 }, |
47 set: function(o, p, value) { | 47 set: function(o, p, value) { |
48 if (!done) loadDeferred(); | 48 if (!done) loadDeferred(); |
49 module[name][p] = value; | 49 module[name][p] = value; |
50 return true; | 50 return true; |
51 }, | 51 }, |
52 }); | 52 }); |
53 }; | 53 }; |
54 | 54 |
55 let reverseDeps = new Map(); | |
vsm
2017/07/06 19:47:28
How about calling this "invalidationMap"?
jakemac
2017/07/06 20:12:11
Changed to `_reverseImports` since that exactly de
| |
55 class LibraryLoader { | 56 class LibraryLoader { |
56 | 57 |
57 constructor(name, defaultValue, imports, loader) { | 58 constructor(name, defaultValue, imports, loader) { |
59 imports.forEach(function(i) { | |
60 var deps = reverseDeps.get(i); | |
61 if (!deps) { | |
62 deps = new Set(); | |
63 reverseDeps.set(i, deps); | |
64 } | |
65 deps.add(name); | |
66 }); | |
58 this._name = name; | 67 this._name = name; |
59 this._library = defaultValue ? defaultValue : {}; | 68 this._library = defaultValue ? defaultValue : {}; |
60 this._imports = imports; | 69 this._imports = imports; |
61 this._loader = loader; | 70 this._loader = loader; |
62 | 71 |
63 // Cyclic import detection | 72 // Cyclic import detection |
64 this._state = LibraryLoader.NOT_LOADED; | 73 this._state = LibraryLoader.NOT_LOADED; |
65 } | 74 } |
66 | 75 |
67 loadImports() { | 76 loadImports() { |
(...skipping 21 matching lines...) Expand all Loading... | |
89 let loader = this; | 98 let loader = this; |
90 let library = this._library; | 99 let library = this._library; |
91 | 100 |
92 library[libraryImports] = this._imports; | 101 library[libraryImports] = this._imports; |
93 library[loadedModule] = library; | 102 library[loadedModule] = library; |
94 args.unshift(library); | 103 args.unshift(library); |
95 | 104 |
96 if (this._name == 'dart_sdk') { | 105 if (this._name == 'dart_sdk') { |
97 // Eagerly load the SDK. | 106 // Eagerly load the SDK. |
98 this._loader.apply(null, args); | 107 this._loader.apply(null, args); |
99 loader._loader = null; | |
100 } else { | 108 } else { |
101 // Load / parse other modules on demand. | 109 // Load / parse other modules on demand. |
102 let done = false; | 110 let done = false; |
103 this._library = new Proxy(library, { | 111 this._library = new Proxy(library, { |
104 get: function(o, name) { | 112 get: function(o, name) { |
105 if (!done) { | 113 if (!done) { |
106 done = true; | 114 done = true; |
107 loader._loader.apply(null, args); | 115 loader._loader.apply(null, args); |
108 loader._loader = null; | |
109 } | 116 } |
110 return o[name]; | 117 return o[name]; |
111 } | 118 } |
112 }); | 119 }); |
113 } | 120 } |
114 | 121 |
115 this._state = LibraryLoader.READY; | 122 this._state = LibraryLoader.READY; |
116 return this._library; | 123 return this._library; |
117 } | 124 } |
118 | 125 |
119 stub() { | 126 stub() { |
120 return this._library; | 127 return this._library; |
121 } | 128 } |
122 } | 129 } |
123 LibraryLoader.NOT_LOADED = 0; | 130 LibraryLoader.NOT_LOADED = 0; |
124 LibraryLoader.LOADING = 1; | 131 LibraryLoader.LOADING = 1; |
125 LibraryLoader.READY = 2; | 132 LibraryLoader.READY = 2; |
126 | 133 |
127 // Map from name to LibraryLoader | 134 // Map from name to LibraryLoader |
128 let libraries = new Map(); | 135 let _libraries = new Map(); |
129 dart_library.libraries = function() { return libraries.keys(); }; | 136 dart_library.libraries = function() { return libraries.keys(); }; |
130 dart_library.debuggerLibraries = function() { | 137 dart_library.debuggerLibraries = function() { |
131 var debuggerLibraries = []; | 138 var debuggerLibraries = []; |
132 libraries.forEach(function (value, key, map) { | 139 _libraries.forEach(function (value, key, map) { |
133 debuggerLibraries.push(value.load()); | 140 debuggerLibraries.push(value.load()); |
134 }); | 141 }); |
135 debuggerLibraries.__proto__ = null; | 142 debuggerLibraries.__proto__ = null; |
136 return debuggerLibraries; | 143 return debuggerLibraries; |
137 }; | 144 }; |
138 | 145 |
146 // Invalidate a library and all things that depend on it | |
147 function _invalidateLibrary(name) { | |
148 let lib = _libraries.get(name); | |
149 if (lib._state == LibraryLoader.NOT_LOADED) return; | |
150 lib._state = LibraryLoader.NOT_LOADED; | |
151 lib._library = {}; | |
152 let deps = reverseDeps.get(name); | |
153 if (!deps) return; | |
154 deps.forEach(_invalidateLibrary); | |
155 } | |
156 | |
139 function library(name, defaultValue, imports, loader) { | 157 function library(name, defaultValue, imports, loader) { |
140 let result = libraries.get(name); | 158 let result = _libraries.get(name); |
141 if (result) { | 159 if (result) { |
142 console.warn('Already loaded ' + name); | 160 console.log('Re-loading ' + name); |
143 return result; | 161 _invalidateLibrary(name); |
144 } | 162 } |
145 result = new LibraryLoader(name, defaultValue, imports, loader); | 163 result = new LibraryLoader(name, defaultValue, imports, loader); |
146 libraries.set(name, result); | 164 _libraries.set(name, result); |
147 return result; | 165 return result; |
148 } | 166 } |
149 dart_library.library = library; | 167 dart_library.library = library; |
150 | 168 |
151 // Maintain a stack of active imports. If a requested library/module is not | 169 // Maintain a stack of active imports. If a requested library/module is not |
152 // available, print the stack to show where/how it was requested. | 170 // available, print the stack to show where/how it was requested. |
153 let _stack = []; | 171 let _stack = []; |
154 function import_(name) { | 172 function import_(name) { |
155 let lib = libraries.get(name); | 173 let lib = _libraries.get(name); |
156 if (!lib) { | 174 if (!lib) { |
157 let message = 'Module ' + name + ' not loaded in the browser.'; | 175 let message = 'Module ' + name + ' not loaded in the browser.'; |
158 if (_stack != []) { | 176 if (_stack != []) { |
159 message += '\nDependency via:'; | 177 message += '\nDependency via:'; |
160 let indent = ''; | 178 let indent = ''; |
161 for (let last = _stack.length - 1; last >= 0; last--) { | 179 for (let last = _stack.length - 1; last >= 0; last--) { |
162 indent += ' '; | 180 indent += ' '; |
163 message += '\n' + indent + '- ' + _stack[last]; | 181 message += '\n' + indent + '- ' + _stack[last]; |
164 } | 182 } |
165 } | 183 } |
166 throwLibraryError(message); | 184 throwLibraryError(message); |
167 } | 185 } |
168 _stack.push(name); | 186 _stack.push(name); |
169 let result = lib.load(); | 187 let result = lib.load(); |
170 _stack.pop(); | 188 _stack.pop(); |
171 return result; | 189 return result; |
172 } | 190 } |
173 dart_library.import = import_; | 191 dart_library.import = import_; |
174 | 192 |
175 var _currentIsolate = false; | 193 var _currentIsolate = false; |
176 | 194 |
177 function start(moduleName, libraryName) { | 195 function _restart() { |
196 start(_lastModuleName, _lastLibraryName, true); | |
197 } | |
198 | |
199 function reload() { | |
200 if (!window.$dartWarmReload) { | |
vsm
2017/07/06 19:47:27
We haven't checked if window exists. Don't really
jakemac
2017/07/06 20:12:11
Done.
| |
201 console.warn('Warm reload not supported in this environment.'); | |
202 return; | |
203 } | |
204 var result; | |
205 if (_lastLibrary && _lastLibrary.onReloadStart) { | |
206 result = _lastLibrary.onReloadStart(); | |
207 } | |
208 if (result && result.then) { | |
209 let sdk = _libraries.get("dart_sdk"); | |
210 result.then(sdk._library.dart.Dynamic)(function() { | |
211 window.$dartWarmReload(_restart); | |
212 }); | |
213 } else { | |
214 window.$dartWarmReload(_restart); | |
215 } | |
216 } | |
217 dart_library.reload = reload; | |
218 | |
219 | |
220 var _lastModuleName; | |
221 var _lastLibraryName; | |
222 var _lastLibrary; | |
223 var _originalBody; | |
224 | |
225 function start(moduleName, libraryName, isReload) { | |
178 if (libraryName == null) libraryName = moduleName; | 226 if (libraryName == null) libraryName = moduleName; |
227 _lastModuleName = moduleName; | |
228 _lastLibraryName = libraryName; | |
179 let library = import_(moduleName)[libraryName]; | 229 let library = import_(moduleName)[libraryName]; |
230 _lastLibrary = library; | |
180 let dart_sdk = import_('dart_sdk'); | 231 let dart_sdk = import_('dart_sdk'); |
181 | 232 |
182 if (!_currentIsolate) { | 233 if (!_currentIsolate) { |
183 // This import is only needed for chrome debugging. We should provide an | 234 // This import is only needed for chrome debugging. We should provide an |
184 // option to compile without it. | 235 // option to compile without it. |
185 dart_sdk._debugger.registerDevtoolsFormatter(); | 236 dart_sdk._debugger.registerDevtoolsFormatter(); |
186 | 237 |
187 // Create isolate. | 238 // Create isolate. |
188 _currentIsolate = true; | 239 _currentIsolate = true; |
189 dart_sdk._isolate_helper.startRootIsolate(() => {}, []); | 240 dart_sdk._isolate_helper.startRootIsolate(() => {}, []); |
190 } | 241 } |
191 | 242 if (isReload) { |
243 if (library.onReloadEnd) { | |
244 library.onReloadEnd(); | |
245 return; | |
246 } else { | |
247 document.body = _originalBody; | |
248 } | |
249 } else { | |
250 // If not a reload then store the initial html to reset it on reload. | |
251 _originalBody = document.body.cloneNode(true); | |
252 } | |
192 library.main(); | 253 library.main(); |
193 } | 254 } |
194 dart_library.start = start; | 255 dart_library.start = start; |
195 | 256 |
196 })(dart_library); | 257 })(dart_library); |
197 } | 258 } |
OLD | NEW |