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 'batch_util.dart'; | 9 import 'batch_util.dart'; |
10 | 10 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 ..addFlag('no-output', negatable: false, help: 'Do not output any files.') | 55 ..addFlag('no-output', negatable: false, help: 'Do not output any files.') |
56 ..addOption('url-mapping', | 56 ..addOption('url-mapping', |
57 allowMultiple: true, | 57 allowMultiple: true, |
58 help: 'A custom url mapping of the form `<scheme>:<name>::<uri>`.') | 58 help: 'A custom url mapping of the form `<scheme>:<name>::<uri>`.') |
59 ..addFlag('verbose', | 59 ..addFlag('verbose', |
60 abbr: 'v', | 60 abbr: 'v', |
61 negatable: false, | 61 negatable: false, |
62 help: 'Print internal warnings and diagnostics to stderr.') | 62 help: 'Print internal warnings and diagnostics to stderr.') |
63 ..addFlag('print-metrics', | 63 ..addFlag('print-metrics', |
64 negatable: false, help: 'Print performance metrics.') | 64 negatable: false, help: 'Print performance metrics.') |
65 ..addOption('write-dependencies', | |
66 help: 'Write all the .dart that were loaded to the given file.') | |
67 ..addFlag('verify-ir', help: 'Perform slow internal correctness checks.') | 65 ..addFlag('verify-ir', help: 'Perform slow internal correctness checks.') |
68 ..addFlag('tolerant', | 66 ..addFlag('tolerant', |
69 help: 'Generate kernel even if there are compile-time errors.', | 67 help: 'Generate kernel even if there are compile-time errors.', |
70 defaultsTo: false) | 68 defaultsTo: false) |
71 ..addOption('D', | 69 ..addOption('D', |
72 abbr: 'D', | 70 abbr: 'D', |
73 allowMultiple: true, | 71 allowMultiple: true, |
74 help: 'Define an environment variable.', | 72 help: 'Define an environment variable.', |
75 hide: true) | 73 hide: true) |
76 ..addFlag('show-external', | 74 ..addFlag('show-external', |
77 help: 'When printing a library as text, also print its dependencies\n' | 75 help: 'When printing a library as text, also print its dependencies\n' |
78 'on external libraries.') | 76 'on external libraries.') |
79 ..addFlag('show-offsets', | 77 ..addFlag('show-offsets', |
80 help: 'When printing a library as text, also print node offsets'); | 78 help: 'When printing a library as text, also print node offsets') |
79 ..addFlag('include-sdk', | |
80 help: 'Include the SDK in the output. Implied by --link.'); | |
81 | 81 |
82 String getUsage() => """ | 82 String getUsage() => """ |
83 Usage: dartk [options] FILE | 83 Usage: dartk [options] FILE |
84 | 84 |
85 Convert .dart or .dill files to kernel's IR and print out its textual | 85 Convert .dart or .dill files to kernel's IR and print out its textual |
86 or binary form. | 86 or binary form. |
87 | 87 |
88 Examples: | 88 Examples: |
89 dartk foo.dart # print text IR for foo.dart | 89 dartk foo.dart # print text IR for foo.dart |
90 dartk foo.dart -ofoo.dill # write binary IR for foo.dart to foo.dill | 90 dartk foo.dart -ofoo.dill # write binary IR for foo.dart to foo.dill |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 } | 259 } |
260 var applicationRoot = new ApplicationRoot(applicationRootOption); | 260 var applicationRoot = new ApplicationRoot(applicationRootOption); |
261 | 261 |
262 // Set up logging. | 262 // Set up logging. |
263 if (options['verbose']) { | 263 if (options['verbose']) { |
264 log.onRecord.listen((LogRecord rec) { | 264 log.onRecord.listen((LogRecord rec) { |
265 stderr.writeln(rec.message); | 265 stderr.writeln(rec.message); |
266 }); | 266 }); |
267 } | 267 } |
268 | 268 |
269 if (options.rest.length != 1) { | 269 bool includeSdk = options['include-sdk']; |
270 return fail('Exactly one FILE should be given.'); | 270 |
271 List<String> inputFiles = options.rest; | |
272 if (inputFiles.length < 1 && !includeSdk) { | |
273 return fail('At least one file should be given.'); | |
271 } | 274 } |
272 | 275 |
273 String file = options.rest.single; | 276 bool hasBinaryInput = false; |
274 checkIsFile(file, option: 'Input file'); | 277 bool hasDartInput = includeSdk; |
275 file = new File(file).absolute.path; | 278 for (String file in inputFiles) { |
276 Uri fileUri = new Uri(scheme: 'file', path: file); | 279 checkIsFile(file, option: 'Input file'); |
280 if (file.endsWith('.dill')) { | |
281 hasBinaryInput = true; | |
282 } else if (file.endsWith('.dart')) { | |
283 hasDartInput = true; | |
284 } else { | |
285 fail('Unrecognized file extension: $file'); | |
286 } | |
287 } | |
288 | |
289 if (hasBinaryInput && hasDartInput) { | |
290 fail('Mixed binary and dart input is not currently supported'); | |
291 } | |
277 | 292 |
278 String format = options['format'] ?? defaultFormat(); | 293 String format = options['format'] ?? defaultFormat(); |
279 String outputFile = options['out'] ?? defaultOutput(); | 294 String outputFile = options['out'] ?? defaultOutput(); |
280 | 295 |
281 List<String> urlMapping = options['url-mapping'] as List<String>; | 296 List<String> urlMapping = options['url-mapping'] as List<String>; |
282 var customUriMappings = parseCustomUriMappings(urlMapping); | 297 var customUriMappings = parseCustomUriMappings(urlMapping); |
283 var repository = new Repository(); | 298 var program = new Program(); |
284 | |
285 Program program; | |
286 | 299 |
287 var watch = new Stopwatch()..start(); | 300 var watch = new Stopwatch()..start(); |
288 List<String> loadedFiles; | |
289 Function getLoadedFiles; | |
290 List errors = const []; | 301 List errors = const []; |
291 TargetFlags targetFlags = new TargetFlags(strongMode: options['strong']); | 302 TargetFlags targetFlags = new TargetFlags(strongMode: options['strong']); |
292 Target target = getTarget(options['target'], targetFlags); | 303 Target target = getTarget(options['target'], targetFlags); |
293 | 304 |
294 var declaredVariables = <String, String>{}; | 305 var declaredVariables = <String, String>{}; |
295 declaredVariables.addAll(target.extraDeclaredVariables); | 306 declaredVariables.addAll(target.extraDeclaredVariables); |
296 for (String define in options['D']) { | 307 for (String define in options['D']) { |
297 int separator = define.indexOf('='); | 308 int separator = define.indexOf('='); |
298 if (separator == -1) { | 309 if (separator == -1) { |
299 fail('Invalid define: -D$define. Format is -D<name>=<value>'); | 310 fail('Invalid define: -D$define. Format is -D<name>=<value>'); |
300 } | 311 } |
301 String name = define.substring(0, separator); | 312 String name = define.substring(0, separator); |
302 String value = define.substring(separator + 1); | 313 String value = define.substring(separator + 1); |
303 declaredVariables[name] = value; | 314 declaredVariables[name] = value; |
304 } | 315 } |
305 | 316 |
306 if (file.endsWith('.dill')) { | 317 DartLoader loader; |
307 program = loadProgramFromBinary(file, repository); | 318 if (hasDartInput) { |
308 getLoadedFiles = () => [file]; | 319 String packageDiscoveryPath = |
309 } else { | 320 batchModeState.isBatchMode || inputFiles.isEmpty |
310 DartOptions dartOptions = new DartOptions( | 321 ? null |
311 strongMode: target.strongMode, | 322 : inputFiles.first; |
312 strongModeSdk: target.strongModeSdk, | 323 loader = await batchModeState.batch.getLoader( |
313 sdk: options['sdk'], | 324 program, |
314 packagePath: packagePath, | 325 new DartOptions( |
315 customUriMappings: customUriMappings, | 326 strongMode: target.strongMode, |
316 declaredVariables: declaredVariables, | 327 strongModeSdk: target.strongModeSdk, |
317 applicationRoot: applicationRoot); | 328 sdk: options['sdk'], |
318 String packageDiscoveryPath = batchModeState.isBatchMode ? null : file; | 329 packagePath: packagePath, |
319 DartLoader loader = await batchModeState.batch.getLoader( | 330 customUriMappings: customUriMappings, |
320 repository, dartOptions, | 331 declaredVariables: declaredVariables, |
332 applicationRoot: applicationRoot), | |
321 packageDiscoveryPath: packageDiscoveryPath); | 333 packageDiscoveryPath: packageDiscoveryPath); |
322 if (options['link']) { | 334 } |
323 program = loader.loadProgram(fileUri, target: target); | 335 |
336 if (includeSdk) { | |
337 for (var uri in batchModeState.batch.dartSdk.uris) { | |
338 loader.loadLibrary(Uri.parse(uri)); | |
339 } | |
340 } | |
341 | |
342 for (String file in inputFiles) { | |
343 file = new File(file).absolute.path; | |
344 Uri fileUri = new Uri(scheme: 'file', path: file); | |
ahe
2017/02/02 16:24:01
Uri.base.resolve(file) should be able to replace t
asgerf
2017/02/03 10:31:16
Done.
| |
345 | |
346 if (file.endsWith('.dill')) { | |
347 loadProgramFromBinary(file, program); | |
324 } else { | 348 } else { |
325 var library = loader.loadLibrary(fileUri); | 349 if (options['link']) { |
326 assert(library == | 350 program = loader.loadProgram(fileUri, target: target); |
327 repository.getLibraryReference(applicationRoot.relativeUri(fileUri))); | 351 } else { |
328 program = new Program(repository.libraries); | 352 var library = loader.loadLibrary(fileUri); |
329 } | 353 assert(library == |
330 errors = loader.errors; | 354 program.getLibraryReference(applicationRoot.relativeUri(fileUri))); |
331 if (errors.isNotEmpty) { | 355 program.mainMethod ??= library.procedures |
332 const int errorLimit = 100; | 356 .firstWhere((p) => p.name.name == 'main', orElse: () => null); |
333 stderr.writeln(errors.take(errorLimit).join('\n')); | 357 } |
334 if (errors.length > errorLimit) { | 358 errors = loader.errors; |
335 stderr | 359 if (errors.isNotEmpty) { |
336 .writeln('[error] ${errors.length - errorLimit} errors not shown'); | 360 const int errorLimit = 100; |
361 stderr.writeln(errors.take(errorLimit).join('\n')); | |
362 if (errors.length > errorLimit) { | |
363 stderr.writeln( | |
364 '[error] ${errors.length - errorLimit} errors not shown'); | |
365 } | |
337 } | 366 } |
338 } | 367 } |
339 getLoadedFiles = () => loadedFiles ??= loader.getLoadedFileNames(); | |
340 } | 368 } |
341 | 369 |
342 bool canContinueCompilation = errors.isEmpty || options['tolerant']; | 370 bool canContinueCompilation = errors.isEmpty || options['tolerant']; |
343 | 371 |
344 int loadTime = watch.elapsedMilliseconds; | 372 int loadTime = watch.elapsedMilliseconds; |
345 if (shouldReportMetrics) { | 373 if (shouldReportMetrics) { |
346 print('loader.time = $loadTime ms'); | 374 print('loader.time = $loadTime ms'); |
347 } | 375 } |
348 | 376 |
349 void runVerifier() { | 377 void runVerifier() { |
350 if (options['verify-ir']) { | 378 if (options['verify-ir']) { |
351 verifyProgram(program); | 379 verifyProgram(program); |
352 } | 380 } |
353 } | 381 } |
354 | 382 |
355 if (canContinueCompilation) { | 383 if (canContinueCompilation) { |
356 runVerifier(); | 384 runVerifier(); |
357 } | 385 } |
358 | 386 |
359 String outputDependencies = options['write-dependencies']; | 387 if (options['link'] && program.mainMethodName == null) { |
360 if (outputDependencies != null) { | 388 fail('[error] The program has no main method.'); |
361 new File(outputDependencies).writeAsStringSync(getLoadedFiles().join('\n')); | |
362 } | 389 } |
363 | 390 |
364 // Apply target-specific transformations. | 391 // Apply target-specific transformations. |
365 if (target != null && options['link'] && canContinueCompilation) { | 392 if (target != null && options['link'] && canContinueCompilation) { |
366 target.transformProgram(program); | 393 target.transformProgram(program); |
367 runVerifier(); | 394 runVerifier(); |
368 } | 395 } |
369 | 396 |
370 if (options['no-output']) { | 397 if (options['no-output']) { |
371 return CompilerOutcome.Ok; | 398 return CompilerOutcome.Ok; |
(...skipping 23 matching lines...) Expand all Loading... | |
395 | 422 |
396 await ioFuture; | 423 await ioFuture; |
397 | 424 |
398 if (shouldReportMetrics) { | 425 if (shouldReportMetrics) { |
399 int flushTime = watch.elapsedMilliseconds - time; | 426 int flushTime = watch.elapsedMilliseconds - time; |
400 print('writer.flush_time = $flushTime ms'); | 427 print('writer.flush_time = $flushTime ms'); |
401 } | 428 } |
402 | 429 |
403 return errors.length > 0 ? CompilerOutcome.Fail : CompilerOutcome.Ok; | 430 return errors.length > 0 ? CompilerOutcome.Fail : CompilerOutcome.Ok; |
404 } | 431 } |
OLD | NEW |