| OLD | NEW |
| 1 #!/usr/bin/env dart | 1 #!/usr/bin/env dart |
| 2 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 import 'dart:async'; | 6 import 'dart:async'; |
| 7 import 'dart:io'; | 7 import 'dart:io'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | 9 import 'package:analyzer/analyzer.dart' |
| 10 show |
| 11 ExportDirective, |
| 12 ImportDirective, |
| 13 PartDirective, |
| 14 StringLiteral, |
| 15 UriBasedDirective, |
| 16 parseDirectives; |
| 10 import 'package:args/args.dart' show ArgParser; | 17 import 'package:args/args.dart' show ArgParser; |
| 11 import 'package:dev_compiler/src/analyzer/context.dart' | |
| 12 show createAnalysisContextWithSources; | |
| 13 import 'package:dev_compiler/src/analyzer/context.dart' | |
| 14 show createAnalysisContextWithSources, AnalyzerOptions; | |
| 15 import 'package:path/path.dart' as path; | 18 import 'package:path/path.dart' as path; |
| 16 | 19 |
| 17 const ENTRY = "main"; | 20 const ENTRY = "main"; |
| 18 | 21 |
| 19 void main(List<String> args) { | 22 void main(List<String> args) { |
| 20 // Parse flags. | 23 // Parse flags. |
| 21 var parser = new ArgParser() | 24 var parser = new ArgParser() |
| 22 ..addOption('out', | 25 ..addOption('out', |
| 23 help: 'Output file (defaults to "out.js")', | 26 help: 'Output file (defaults to "out.js")', |
| 24 abbr: 'o', | 27 abbr: 'o', |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 template.add('--unsafe-force-compile'); | 62 template.add('--unsafe-force-compile'); |
| 60 } | 63 } |
| 61 | 64 |
| 62 // Compute the transitive closure | 65 // Compute the transitive closure |
| 63 var total = new Stopwatch()..start(); | 66 var total = new Stopwatch()..start(); |
| 64 var partial = new Stopwatch()..start(); | 67 var partial = new Stopwatch()..start(); |
| 65 | 68 |
| 66 // TODO(vsm): We're using the analyzer just to compute the import/export/part | 69 // TODO(vsm): We're using the analyzer just to compute the import/export/part |
| 67 // dependence graph. This is expensive. Is there a lighterweight way to do | 70 // dependence graph. This is expensive. Is there a lighterweight way to do |
| 68 // this? | 71 // this? |
| 69 var context = createAnalysisContextWithSources(new AnalyzerOptions()); | 72 transitiveFiles(entry, Directory.current.path, packageRoot); |
| 70 transitiveFiles(context, entry, Directory.current.path); | |
| 71 orderModules(); | 73 orderModules(); |
| 72 computeTransitiveDependences(); | 74 computeTransitiveDependences(); |
| 73 | 75 |
| 74 var graphTime = partial.elapsedMilliseconds / 1000; | 76 var graphTime = partial.elapsedMilliseconds / 1000; |
| 75 print('Computed global build graph in $graphTime seconds'); | 77 print('Computed global build graph in $graphTime seconds'); |
| 76 | 78 |
| 77 // Prepend Dart runtime files to the output | 79 // Prepend Dart runtime files to the output |
| 78 var out = new File(outfile); | 80 var out = new File(outfile); |
| 79 var dartLibrary = | 81 var dartLibrary = |
| 80 new File(path.join(ddcPath, 'lib', 'runtime', 'dart_library.js')) | 82 new File(path.join(ddcPath, 'lib', 'runtime', 'dart_library.js')) |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 if (fromModule == toModule || toModule == 'dart') return; | 229 if (fromModule == toModule || toModule == 'dart') return; |
| 228 dependenceMap.putIfAbsent(fromModule, () => new Set<String>()); | 230 dependenceMap.putIfAbsent(fromModule, () => new Set<String>()); |
| 229 dependenceMap[fromModule].add(toModule); | 231 dependenceMap[fromModule].add(toModule); |
| 230 } | 232 } |
| 231 | 233 |
| 232 String canonicalize(String uri, String root) { | 234 String canonicalize(String uri, String root) { |
| 233 var sourceUri = Uri.parse(uri); | 235 var sourceUri = Uri.parse(uri); |
| 234 if (sourceUri.scheme == '') { | 236 if (sourceUri.scheme == '') { |
| 235 sourceUri = path.toUri( | 237 sourceUri = path.toUri( |
| 236 path.isAbsolute(uri) ? path.absolute(uri) : path.join(root, uri)); | 238 path.isAbsolute(uri) ? path.absolute(uri) : path.join(root, uri)); |
| 239 return sourceUri.path; |
| 237 } | 240 } |
| 238 return sourceUri.toString(); | 241 return sourceUri.toString(); |
| 239 } | 242 } |
| 240 | 243 |
| 241 void transitiveFiles(AnalysisContext context, String entryPoint, String root) { | 244 /// Simplified from ParseDartTask.resolveDirective. |
| 245 String _resolveDirective(UriBasedDirective directive) { |
| 246 StringLiteral uriLiteral = directive.uri; |
| 247 String uriContent = uriLiteral.stringValue; |
| 248 if (uriContent != null) { |
| 249 uriContent = uriContent.trim(); |
| 250 directive.uriContent = uriContent; |
| 251 } |
| 252 return directive.validate() == null ? uriContent : null; |
| 253 } |
| 254 |
| 255 String _loadFile(String uri, String packageRoot) { |
| 256 if (uri.startsWith('package:')) { |
| 257 uri = path.join(packageRoot, uri.substring(8)); |
| 258 } |
| 259 return new File(uri).readAsStringSync(); |
| 260 } |
| 261 |
| 262 void transitiveFiles(String entryPoint, String root, String packageRoot) { |
| 242 entryPoint = canonicalize(entryPoint, root); | 263 entryPoint = canonicalize(entryPoint, root); |
| 243 if (entryPoint.startsWith('dart:')) return; | 264 if (entryPoint.startsWith('dart:')) return; |
| 244 var entryDir = path.dirname(entryPoint); | |
| 245 if (processFile(entryPoint)) { | 265 if (processFile(entryPoint)) { |
| 246 // Process this | 266 // Process this |
| 247 var source = context.sourceFactory.forUri(entryPoint); | 267 var source = _loadFile(entryPoint, packageRoot); |
| 248 if (source == null) { | 268 var entryDir = path.dirname(entryPoint); |
| 249 throw new Exception('could not create a source for $entryPoint.' | 269 var unit = parseDirectives(source, name: entryPoint, suppressErrors: true); |
| 250 ' The file name is in the wrong format or was not found.'); | 270 for (var d in unit.directives) { |
| 251 } | 271 if (d is ImportDirective || d is ExportDirective) { |
| 252 var library = context.computeLibraryElement(source); | 272 var uri = _resolveDirective(d); |
| 253 for (var entry in library.imports) { | 273 processDependence(entryPoint, canonicalize(uri, entryDir)); |
| 254 if (entry.uri == null) continue; | 274 transitiveFiles(uri, entryDir, packageRoot); |
| 255 processDependence(entryPoint, canonicalize(entry.uri, entryDir)); | 275 } else if (d is PartDirective) { |
| 256 transitiveFiles(context, entry.uri, entryDir); | 276 var uri = _resolveDirective(d); |
| 257 } | 277 processFile(canonicalize(uri, entryDir)); |
| 258 for (var entry in library.exports) { | 278 } |
| 259 processDependence(entryPoint, canonicalize(entry.uri, entryDir)); | |
| 260 transitiveFiles(context, entry.uri, entryDir); | |
| 261 } | |
| 262 for (var part in library.parts) { | |
| 263 processFile(canonicalize(part.uri, entryDir)); | |
| 264 } | 279 } |
| 265 } | 280 } |
| 266 } | 281 } |
| OLD | NEW |