| 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 /// Development server that compiles Dart to JS on the fly. | 5 /// Development server that compiles Dart to JS on the fly. |
| 6 library dev_compiler.src.server; | 6 library dev_compiler.src.server; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 import 'dart:io'; | 10 import 'dart:io'; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 resourceOutputPath(node.uri, _entryNode.uri, options.runtimeDir); | 127 resourceOutputPath(node.uri, _entryNode.uri, options.runtimeDir); |
| 128 assert(filepath != null); | 128 assert(filepath != null); |
| 129 filepath = path.join(outputDir, filepath); | 129 filepath = path.join(outputDir, filepath); |
| 130 var dir = path.dirname(filepath); | 130 var dir = path.dirname(filepath); |
| 131 new Directory(dir).createSync(recursive: true); | 131 new Directory(dir).createSync(recursive: true); |
| 132 new File.fromUri(node.source.uri).copySync(filepath); | 132 new File.fromUri(node.source.uri).copySync(filepath); |
| 133 if (_hashing) node.cachingHash = computeHashFromFile(filepath); | 133 if (_hashing) node.cachingHash = computeHashFromFile(filepath); |
| 134 } | 134 } |
| 135 | 135 |
| 136 void _buildDartLibrary(DartSourceNode node) { | 136 void _buildDartLibrary(DartSourceNode node) { |
| 137 print('Compiling ${node.uri}'); |
| 137 var source = node.source; | 138 var source = node.source; |
| 138 // TODO(sigmund): find out from analyzer team if there is a better way | 139 // TODO(sigmund): find out from analyzer team if there is a better way |
| 139 context.applyChanges(new ChangeSet()..changedSource(source)); | 140 context.applyChanges(new ChangeSet()..changedSource(source)); |
| 140 var entryUnit = context.resolveCompilationUnit2(source, source); | 141 var entryUnit = context.resolveCompilationUnit2(source, source); |
| 141 var lib = entryUnit.element.enclosingElement; | 142 var lib = entryUnit.element.enclosingElement; |
| 142 if (!options.checkSdk && lib.source.uri.scheme == 'dart') return; | 143 if (!options.checkSdk && lib.source.uri.scheme == 'dart') return; |
| 143 var current = node.info; | 144 var current = node.info; |
| 144 if (current != null) { | 145 if (current != null) { |
| 145 assert(current.library == lib); | 146 assert(current.library == lib); |
| 146 } else { | 147 } else { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 // TODO(jmesserly): this logic is duplicated in a few places | 247 // TODO(jmesserly): this logic is duplicated in a few places |
| 247 this._entryPath = compiler.options.sourceOptions.useImplicitHtml | 248 this._entryPath = compiler.options.sourceOptions.useImplicitHtml |
| 248 ? SourceResolverOptions.implicitHtmlFile | 249 ? SourceResolverOptions.implicitHtmlFile |
| 249 : entryPath; | 250 : entryPath; |
| 250 | 251 |
| 251 Future start() async { | 252 Future start() async { |
| 252 // Create output directory if needed. shelf_static will fail otherwise. | 253 // Create output directory if needed. shelf_static will fail otherwise. |
| 253 var out = new Directory(outDir); | 254 var out = new Directory(outDir); |
| 254 if (!await out.exists()) await out.create(recursive: true); | 255 if (!await out.exists()) await out.create(recursive: true); |
| 255 | 256 |
| 257 var mainHandler = |
| 258 shelf_static.createStaticHandler(outDir, defaultDocument: _entryPath); |
| 259 var sourceHandler = shelf_static.createStaticHandler(compiler.inputBaseDir, |
| 260 serveFilesOutsidePath: true); |
| 261 var topLevelHandler = (shelf.Request request) { |
| 262 var path = request.url.path; |
| 263 if (path.endsWith('.dart')) { |
| 264 return sourceHandler(request); |
| 265 } else { |
| 266 return mainHandler(request); |
| 267 } |
| 268 }; |
| 269 |
| 256 var handler = const shelf.Pipeline() | 270 var handler = const shelf.Pipeline() |
| 257 .addMiddleware(rebuildAndCache) | 271 .addMiddleware(rebuildAndCache) |
| 258 .addHandler(shelf_static.createStaticHandler(outDir, | 272 .addHandler(topLevelHandler); |
| 259 defaultDocument: _entryPath)); | |
| 260 await shelf.serve(handler, host, port); | 273 await shelf.serve(handler, host, port); |
| 261 print('Serving $_entryPath at http://$host:$port/'); | 274 print('Serving $_entryPath at http://$host:$port/'); |
| 262 // Give the compiler a head start. This is not needed for correctness, | 275 // Give the compiler a head start. This is not needed for correctness, |
| 263 // but will likely speed up the first load. Regardless of whether compile | 276 // but will likely speed up the first load. Regardless of whether compile |
| 264 // succeeds we should still start the server. | 277 // succeeds we should still start the server. |
| 265 compiler.run(); | 278 compiler.run(); |
| 266 // Server has started so this future will complete. | 279 // Server has started so this future will complete. |
| 267 } | 280 } |
| 268 | 281 |
| 269 shelf.Handler rebuildAndCache(shelf.Handler handler) => (request) { | 282 shelf.Handler rebuildAndCache(shelf.Handler handler) => (request) { |
| 270 print('requested $GREEN_COLOR${request.url}$NO_COLOR'); | |
| 271 // Trigger recompile only when requesting the HTML page. | 283 // Trigger recompile only when requesting the HTML page. |
| 272 var segments = request.url.pathSegments; | 284 var segments = request.url.pathSegments; |
| 273 bool isEntryPage = segments.length == 0 || segments[0] == _entryPath; | 285 bool isEntryPage = segments.length == 0 || segments[0] == _entryPath; |
| 274 if (isEntryPage) compiler._runAgain(); | 286 if (isEntryPage) compiler._runAgain(); |
| 275 | 287 |
| 276 // To help browsers cache resources that don't change, we serve these | 288 // To help browsers cache resources that don't change, we serve these |
| 277 // resources by adding a query parameter containing their hash: | 289 // resources by adding a query parameter containing their hash: |
| 278 // /{path-to-file.js}?____cached={hash} | 290 // /{path-to-file.js}?____cached={hash} |
| 279 var hash = request.url.queryParameters['____cached']; | 291 var hash = request.url.queryParameters['____cached']; |
| 280 var response = handler(request); | 292 var response = handler(request); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 308 Source resolveAbsolute(Uri uri, [Uri actualUri]) { | 320 Source resolveAbsolute(Uri uri, [Uri actualUri]) { |
| 309 var src = resolver.resolveAbsolute(uri, actualUri); | 321 var src = resolver.resolveAbsolute(uri, actualUri); |
| 310 return src.exists() ? src : null; | 322 return src.exists() ? src : null; |
| 311 } | 323 } |
| 312 | 324 |
| 313 Uri restoreAbsolute(Source source) => resolver.restoreAbsolute(source); | 325 Uri restoreAbsolute(Source source) => resolver.restoreAbsolute(source); |
| 314 } | 326 } |
| 315 | 327 |
| 316 final _log = new Logger('dev_compiler.src.server'); | 328 final _log = new Logger('dev_compiler.src.server'); |
| 317 final _earlyErrorResult = new CheckerResults(const [], true); | 329 final _earlyErrorResult = new CheckerResults(const [], true); |
| OLD | NEW |