| 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 library analyzer_cli.src.driver; | 5 library analyzer_cli.src.driver; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 | 10 |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 // TODO(paulberry): diet parse 'package:' imports when we don't want | 323 // TODO(paulberry): diet parse 'package:' imports when we don't want |
| 324 // diagnostics. (Full parse is still needed for "self" packages.) | 324 // diagnostics. (Full parse is still needed for "self" packages.) |
| 325 return true; | 325 return true; |
| 326 } | 326 } |
| 327 }; | 327 }; |
| 328 } | 328 } |
| 329 | 329 |
| 330 /// Decide on the appropriate method for resolving URIs based on the given | 330 /// Decide on the appropriate method for resolving URIs based on the given |
| 331 /// [options] and [customUrlMappings] settings, and return a | 331 /// [options] and [customUrlMappings] settings, and return a |
| 332 /// [SourceFactory] that has been configured accordingly. | 332 /// [SourceFactory] that has been configured accordingly. |
| 333 SourceFactory _chooseUriResolutionPolicy( | 333 SourceFactory _chooseUriResolutionPolicy(CommandLineOptions options, |
| 334 CommandLineOptions options, EmbedderYamlLocator yamlLocator) { | 334 Map<fileSystem.Folder, YamlMap> embedderMap, _PackageInfo packageInfo) { |
| 335 Packages packages; | |
| 336 Map<String, List<fileSystem.Folder>> packageMap; | |
| 337 UriResolver packageUriResolver; | |
| 338 | |
| 339 // Create a custom package resolver if one has been specified. | 335 // Create a custom package resolver if one has been specified. |
| 340 if (packageResolverProvider != null) { | 336 if (packageResolverProvider != null) { |
| 341 fileSystem.Folder folder = | 337 fileSystem.Folder folder = |
| 342 PhysicalResourceProvider.INSTANCE.getResource('.'); | 338 PhysicalResourceProvider.INSTANCE.getResource('.'); |
| 343 UriResolver resolver = packageResolverProvider(folder); | 339 UriResolver resolver = packageResolverProvider(folder); |
| 344 if (resolver != null) { | 340 if (resolver != null) { |
| 345 UriResolver sdkResolver; | 341 UriResolver sdkResolver; |
| 346 | 342 |
| 347 // Check for a resolver provider. | 343 // Check for a resolver provider. |
| 348 if (embeddedUriResolverProvider != null) { | 344 if (embeddedUriResolverProvider != null) { |
| 349 EmbedderUriResolver embedderUriResolver = | 345 EmbedderUriResolver embedderUriResolver = |
| 350 embeddedUriResolverProvider(folder); | 346 embeddedUriResolverProvider(folder); |
| 351 if (embedderUriResolver != null && embedderUriResolver.length != 0) { | 347 if (embedderUriResolver != null && embedderUriResolver.length != 0) { |
| 352 sdkResolver = embedderUriResolver; | 348 sdkResolver = embedderUriResolver; |
| 353 } | 349 } |
| 354 } | 350 } |
| 355 | 351 |
| 356 // Default to a Dart URI resolver if no embedder is found. | 352 // Default to a Dart URI resolver if no embedder is found. |
| 357 sdkResolver ??= new DartUriResolver(sdk); | 353 sdkResolver ??= new DartUriResolver(sdk); |
| 358 | 354 |
| 359 // TODO(brianwilkerson) This doesn't sdk extensions. | 355 // TODO(brianwilkerson) This doesn't sdk extensions. |
| 360 List<UriResolver> resolvers = <UriResolver>[ | 356 List<UriResolver> resolvers = <UriResolver>[ |
| 361 sdkResolver, | 357 sdkResolver, |
| 362 resolver, | 358 resolver, |
| 363 new FileUriResolver() | 359 new FileUriResolver() |
| 364 ]; | 360 ]; |
| 365 return new SourceFactory(resolvers); | 361 return new SourceFactory(resolvers); |
| 366 } | 362 } |
| 367 } | 363 } |
| 368 // Process options, caching package resolution details. | |
| 369 if (options.packageConfigPath != null) { | |
| 370 String packageConfigPath = options.packageConfigPath; | |
| 371 Uri fileUri = new Uri.file(packageConfigPath); | |
| 372 try { | |
| 373 File configFile = new File.fromUri(fileUri).absolute; | |
| 374 List<int> bytes = configFile.readAsBytesSync(); | |
| 375 Map<String, Uri> map = pkgfile.parse(bytes, configFile.uri); | |
| 376 packages = new MapPackages(map); | |
| 377 packageMap = _getPackageMap(packages); | |
| 378 } catch (e) { | |
| 379 printAndFail( | |
| 380 'Unable to read package config data from $packageConfigPath: $e'); | |
| 381 } | |
| 382 } else if (options.packageRootPath != null) { | |
| 383 packageMap = _PackageRootPackageMapBuilder | |
| 384 .buildPackageMap(options.packageRootPath); | |
| 385 | 364 |
| 365 UriResolver packageUriResolver; |
| 366 |
| 367 if (options.packageRootPath != null) { |
| 386 JavaFile packageDirectory = new JavaFile(options.packageRootPath); | 368 JavaFile packageDirectory = new JavaFile(options.packageRootPath); |
| 387 packageUriResolver = new PackageUriResolver([packageDirectory]); | 369 packageUriResolver = new PackageUriResolver([packageDirectory]); |
| 388 } else { | 370 } else if (options.packageConfigPath == null) { |
| 389 fileSystem.Resource cwd = | 371 // TODO(pq): remove? |
| 390 PhysicalResourceProvider.INSTANCE.getResource('.'); | 372 if (packageInfo.packageMap == null) { |
| 391 | |
| 392 // Look for .packages. | |
| 393 packages = _discoverPackagespec(new Uri.directory(cwd.path)); | |
| 394 | |
| 395 if (packages != null) { | |
| 396 packageMap = _getPackageMap(packages); | |
| 397 } else { | |
| 398 // Fall back to pub list-package-dirs. | 373 // Fall back to pub list-package-dirs. |
| 399 | |
| 400 PubPackageMapProvider pubPackageMapProvider = | 374 PubPackageMapProvider pubPackageMapProvider = |
| 401 new PubPackageMapProvider(PhysicalResourceProvider.INSTANCE, sdk); | 375 new PubPackageMapProvider(PhysicalResourceProvider.INSTANCE, sdk); |
| 376 fileSystem.Resource cwd = |
| 377 PhysicalResourceProvider.INSTANCE.getResource('.'); |
| 402 PackageMapInfo packageMapInfo = | 378 PackageMapInfo packageMapInfo = |
| 403 pubPackageMapProvider.computePackageMap(cwd); | 379 pubPackageMapProvider.computePackageMap(cwd); |
| 404 packageMap = packageMapInfo.packageMap; | 380 Map<String, List<fileSystem.Folder>> packageMap = |
| 381 packageMapInfo.packageMap; |
| 405 | 382 |
| 406 // Only create a packageUriResolver if pub list-package-dirs succeeded. | 383 // Only create a packageUriResolver if pub list-package-dirs succeeded. |
| 407 // If it failed, that's not a problem; it simply means we have no way | 384 // If it failed, that's not a problem; it simply means we have no way |
| 408 // to resolve packages. | 385 // to resolve packages. |
| 409 if (packageMapInfo.packageMap != null) { | 386 if (packageMapInfo.packageMap != null) { |
| 410 packageUriResolver = new PackageMapUriResolver( | 387 packageUriResolver = new PackageMapUriResolver( |
| 411 PhysicalResourceProvider.INSTANCE, packageMap); | 388 PhysicalResourceProvider.INSTANCE, packageMap); |
| 412 } | 389 } |
| 413 } | 390 } |
| 414 } | 391 } |
| 415 | 392 |
| 416 // Now, build our resolver list. | 393 // Now, build our resolver list. |
| 417 List<UriResolver> resolvers = []; | 394 List<UriResolver> resolvers = []; |
| 418 | 395 |
| 419 // 'dart:' URIs come first. | 396 // 'dart:' URIs come first. |
| 420 | 397 |
| 421 // Setup embedding. | 398 // Setup embedding. |
| 422 yamlLocator.refresh(packageMap); | |
| 423 | |
| 424 EmbedderUriResolver embedderUriResolver = | 399 EmbedderUriResolver embedderUriResolver = |
| 425 new EmbedderUriResolver(yamlLocator.embedderYamls); | 400 new EmbedderUriResolver(embedderMap); |
| 426 if (embedderUriResolver.length == 0) { | 401 if (embedderUriResolver.length == 0) { |
| 427 // The embedder uri resolver has no mappings. Use the default Dart SDK | 402 // The embedder uri resolver has no mappings. Use the default Dart SDK |
| 428 // uri resolver. | 403 // uri resolver. |
| 429 resolvers.add(new DartUriResolver(sdk)); | 404 resolvers.add(new DartUriResolver(sdk)); |
| 430 } else { | 405 } else { |
| 431 // The embedder uri resolver has mappings, use it instead of the default | 406 // The embedder uri resolver has mappings, use it instead of the default |
| 432 // Dart SDK uri resolver. | 407 // Dart SDK uri resolver. |
| 433 resolvers.add(embedderUriResolver); | 408 resolvers.add(embedderUriResolver); |
| 434 } | 409 } |
| 435 | 410 |
| 436 // Next SdkExts. | 411 // Next SdkExts. |
| 437 if (packageMap != null) { | 412 if (packageInfo.packageMap != null) { |
| 438 resolvers.add(new SdkExtUriResolver(packageMap)); | 413 resolvers.add(new SdkExtUriResolver(packageInfo.packageMap)); |
| 439 } | 414 } |
| 440 | 415 |
| 441 // Then package URIs. | 416 // Then package URIs. |
| 442 if (packageUriResolver != null) { | 417 if (packageUriResolver != null) { |
| 443 resolvers.add(packageUriResolver); | 418 resolvers.add(packageUriResolver); |
| 444 } | 419 } |
| 445 | 420 |
| 446 // Finally files. | 421 // Finally files. |
| 447 resolvers.add(new FileUriResolver()); | 422 resolvers.add(new FileUriResolver()); |
| 448 | 423 |
| 449 return new SourceFactory(resolvers, packages); | 424 return new SourceFactory(resolvers, packageInfo.packages); |
| 450 } | 425 } |
| 451 | 426 |
| 452 /// Collect all analyzable files at [filePath], recursively if it's a | 427 /// Collect all analyzable files at [filePath], recursively if it's a |
| 453 /// directory, ignoring links. | 428 /// directory, ignoring links. |
| 454 Iterable<File> _collectFiles(String filePath) { | 429 Iterable<File> _collectFiles(String filePath) { |
| 455 List<File> files = <File>[]; | 430 List<File> files = <File>[]; |
| 456 File file = new File(filePath); | 431 File file = new File(filePath); |
| 457 if (file.existsSync()) { | 432 if (file.existsSync()) { |
| 458 files.add(file); | 433 files.add(file); |
| 459 } else { | 434 } else { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 // Create a context. | 481 // Create a context. |
| 507 _context = AnalysisEngine.instance.createAnalysisContext(); | 482 _context = AnalysisEngine.instance.createAnalysisContext(); |
| 508 | 483 |
| 509 AnalyzeFunctionBodiesPredicate dietParsingPolicy = | 484 AnalyzeFunctionBodiesPredicate dietParsingPolicy = |
| 510 _chooseDietParsingPolicy(options); | 485 _chooseDietParsingPolicy(options); |
| 511 setAnalysisContextOptions(_context, options, | 486 setAnalysisContextOptions(_context, options, |
| 512 (AnalysisOptionsImpl contextOptions) { | 487 (AnalysisOptionsImpl contextOptions) { |
| 513 contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy; | 488 contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy; |
| 514 }); | 489 }); |
| 515 | 490 |
| 516 // Once options are processed, setup the SDK. | 491 // Find package info. |
| 517 _setupSdk(options); | 492 _PackageInfo packageInfo = _findPackages(options); |
| 493 |
| 494 // Process embedders. |
| 495 Map<fileSystem.Folder, YamlMap> embedderMap = |
| 496 _findEmbedders(packageInfo.packageMap); |
| 497 |
| 498 // Once options and embedders are processed, setup the SDK. |
| 499 _setupSdk(options, embedderMap.isNotEmpty); |
| 518 | 500 |
| 519 // Choose a package resolution policy and a diet parsing policy based on | 501 // Choose a package resolution policy and a diet parsing policy based on |
| 520 // the command-line options. | 502 // the command-line options. |
| 521 SourceFactory sourceFactory = _chooseUriResolutionPolicy( | 503 SourceFactory sourceFactory = |
| 522 options, (_context as InternalAnalysisContext).embedderYamlLocator); | 504 _chooseUriResolutionPolicy(options, embedderMap, packageInfo); |
| 523 | 505 |
| 524 _context.sourceFactory = sourceFactory; | 506 _context.sourceFactory = sourceFactory; |
| 525 } | 507 } |
| 526 | 508 |
| 527 /// Return discovered packagespec, or `null` if none is found. | 509 /// Return discovered packagespec, or `null` if none is found. |
| 528 Packages _discoverPackagespec(Uri root) { | 510 Packages _discoverPackagespec(Uri root) { |
| 529 try { | 511 try { |
| 530 Packages packages = pkgDiscovery.findPackagesFromFile(root); | 512 Packages packages = pkgDiscovery.findPackagesFromFile(root); |
| 531 if (packages != Packages.noPackages) { | 513 if (packages != Packages.noPackages) { |
| 532 return packages; | 514 return packages; |
| 533 } | 515 } |
| 534 } catch (_) { | 516 } catch (_) { |
| 535 // Ignore and fall through to null. | 517 // Ignore and fall through to null. |
| 536 } | 518 } |
| 537 | 519 |
| 538 return null; | 520 return null; |
| 539 } | 521 } |
| 540 | 522 |
| 523 Map<fileSystem.Folder, YamlMap> _findEmbedders( |
| 524 Map<String, List<fileSystem.Folder>> packageMap) { |
| 525 EmbedderYamlLocator locator = |
| 526 (_context as InternalAnalysisContext).embedderYamlLocator; |
| 527 locator.refresh(packageMap); |
| 528 return locator.embedderYamls; |
| 529 } |
| 530 |
| 531 _PackageInfo _findPackages(CommandLineOptions options) { |
| 532 if (packageResolverProvider != null) { |
| 533 // The resolver provider will do all the work later. |
| 534 return null; |
| 535 } |
| 536 |
| 537 Packages packages; |
| 538 Map<String, List<fileSystem.Folder>> packageMap; |
| 539 |
| 540 if (options.packageConfigPath != null) { |
| 541 String packageConfigPath = options.packageConfigPath; |
| 542 Uri fileUri = new Uri.file(packageConfigPath); |
| 543 try { |
| 544 File configFile = new File.fromUri(fileUri).absolute; |
| 545 List<int> bytes = configFile.readAsBytesSync(); |
| 546 Map<String, Uri> map = pkgfile.parse(bytes, configFile.uri); |
| 547 packages = new MapPackages(map); |
| 548 packageMap = _getPackageMap(packages); |
| 549 } catch (e) { |
| 550 printAndFail( |
| 551 'Unable to read package config data from $packageConfigPath: $e'); |
| 552 } |
| 553 } else if (options.packageRootPath != null) { |
| 554 packageMap = _PackageRootPackageMapBuilder |
| 555 .buildPackageMap(options.packageRootPath); |
| 556 } else { |
| 557 fileSystem.Resource cwd = |
| 558 PhysicalResourceProvider.INSTANCE.getResource('.'); |
| 559 // Look for .packages. |
| 560 packages = _discoverPackagespec(new Uri.directory(cwd.path)); |
| 561 packageMap = _getPackageMap(packages); |
| 562 } |
| 563 |
| 564 return new _PackageInfo(packages, packageMap); |
| 565 } |
| 566 |
| 541 Map<String, List<fileSystem.Folder>> _getPackageMap(Packages packages) { | 567 Map<String, List<fileSystem.Folder>> _getPackageMap(Packages packages) { |
| 542 if (packages == null) { | 568 if (packages == null) { |
| 543 return null; | 569 return null; |
| 544 } | 570 } |
| 545 | 571 |
| 546 Map<String, List<fileSystem.Folder>> folderMap = | 572 Map<String, List<fileSystem.Folder>> folderMap = |
| 547 new Map<String, List<fileSystem.Folder>>(); | 573 new Map<String, List<fileSystem.Folder>>(); |
| 548 packages.asMap().forEach((String packagePath, Uri uri) { | 574 packages.asMap().forEach((String packagePath, Uri uri) { |
| 549 folderMap[packagePath] = [ | 575 folderMap[packagePath] = [ |
| 550 PhysicalResourceProvider.INSTANCE.getFolder(path.fromUri(uri)) | 576 PhysicalResourceProvider.INSTANCE.getFolder(path.fromUri(uri)) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 577 var errorSeverity = analyzer.analyzeSync(); | 603 var errorSeverity = analyzer.analyzeSync(); |
| 578 if (errorSeverity == ErrorSeverity.ERROR) { | 604 if (errorSeverity == ErrorSeverity.ERROR) { |
| 579 exitCode = errorSeverity.ordinal; | 605 exitCode = errorSeverity.ordinal; |
| 580 } | 606 } |
| 581 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) { | 607 if (options.warningsAreFatal && errorSeverity == ErrorSeverity.WARNING) { |
| 582 exitCode = errorSeverity.ordinal; | 608 exitCode = errorSeverity.ordinal; |
| 583 } | 609 } |
| 584 return errorSeverity; | 610 return errorSeverity; |
| 585 } | 611 } |
| 586 | 612 |
| 587 void _setupSdk(CommandLineOptions options) { | 613 void _setupSdk(CommandLineOptions options, bool hasEmbedder) { |
| 588 if (sdk == null) { | 614 if (sdk == null) { |
| 589 if (options.dartSdkSummaryPath != null) { | 615 if (options.dartSdkSummaryPath != null) { |
| 590 sdk = new SummaryBasedDartSdk(options.dartSdkSummaryPath); | 616 sdk = new SummaryBasedDartSdk(options.dartSdkSummaryPath); |
| 591 } else { | 617 } else { |
| 592 String dartSdkPath = options.dartSdkPath; | 618 String dartSdkPath = options.dartSdkPath; |
| 593 DirectoryBasedDartSdk directorySdk = | 619 DirectoryBasedDartSdk directorySdk = |
| 594 new DirectoryBasedDartSdk(new JavaFile(dartSdkPath)); | 620 new DirectoryBasedDartSdk(new JavaFile(dartSdkPath)); |
| 595 directorySdk.useSummary = | 621 // Summaries are disabled in the presence of embedders. |
| 596 options.sourceFiles.every((String sourcePath) { | 622 if (hasEmbedder) { |
| 597 sourcePath = path.absolute(sourcePath); | 623 directorySdk.useSummary = false; |
| 598 sourcePath = path.normalize(sourcePath); | 624 } else { |
| 599 return !path.isWithin(dartSdkPath, sourcePath); | 625 directorySdk.useSummary = |
| 600 }); | 626 options.sourceFiles.every((String sourcePath) { |
| 627 sourcePath = path.absolute(sourcePath); |
| 628 sourcePath = path.normalize(sourcePath); |
| 629 return !path.isWithin(dartSdkPath, sourcePath); |
| 630 }); |
| 631 } |
| 601 directorySdk.analysisOptions = context.analysisOptions; | 632 directorySdk.analysisOptions = context.analysisOptions; |
| 602 sdk = directorySdk; | 633 sdk = directorySdk; |
| 603 } | 634 } |
| 604 } | 635 } |
| 605 } | 636 } |
| 606 | 637 |
| 607 static AnalysisOptionsImpl createAnalysisOptionsForCommandLineOptions( | 638 static AnalysisOptionsImpl createAnalysisOptionsForCommandLineOptions( |
| 608 CommandLineOptions options) { | 639 CommandLineOptions options) { |
| 609 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); | 640 AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl(); |
| 610 contextOptions.hint = !options.disableHints; | 641 contextOptions.hint = !options.disableHints; |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 } | 798 } |
| 768 }); | 799 }); |
| 769 } | 800 } |
| 770 } | 801 } |
| 771 | 802 |
| 772 class _DriverError implements Exception { | 803 class _DriverError implements Exception { |
| 773 String msg; | 804 String msg; |
| 774 _DriverError(this.msg); | 805 _DriverError(this.msg); |
| 775 } | 806 } |
| 776 | 807 |
| 808 class _PackageInfo { |
| 809 Packages packages; |
| 810 Map<String, List<fileSystem.Folder>> packageMap; |
| 811 _PackageInfo(this.packages, this.packageMap); |
| 812 } |
| 813 |
| 777 /// [SdkExtUriResolver] needs a Map from package name to folder. In the case | 814 /// [SdkExtUriResolver] needs a Map from package name to folder. In the case |
| 778 /// that the analyzer is invoked with a --package-root option, we need to | 815 /// that the analyzer is invoked with a --package-root option, we need to |
| 779 /// manually create this mapping. Given [packageRootPath], | 816 /// manually create this mapping. Given [packageRootPath], |
| 780 /// [_PackageRootPackageMapBuilder] creates a simple mapping from package name | 817 /// [_PackageRootPackageMapBuilder] creates a simple mapping from package name |
| 781 /// to full path on disk (resolving any symbolic links). | 818 /// to full path on disk (resolving any symbolic links). |
| 782 class _PackageRootPackageMapBuilder { | 819 class _PackageRootPackageMapBuilder { |
| 783 static Map<String, List<fileSystem.Folder>> buildPackageMap( | 820 static Map<String, List<fileSystem.Folder>> buildPackageMap( |
| 784 String packageRootPath) { | 821 String packageRootPath) { |
| 785 var packageRoot = new Directory(packageRootPath); | 822 var packageRoot = new Directory(packageRootPath); |
| 786 if (!packageRoot.existsSync()) { | 823 if (!packageRoot.existsSync()) { |
| 787 throw new _DriverError( | 824 throw new _DriverError( |
| 788 'Package root directory ($packageRootPath) does not exist.'); | 825 'Package root directory ($packageRootPath) does not exist.'); |
| 789 } | 826 } |
| 790 var packages = packageRoot.listSync(followLinks: false); | 827 var packages = packageRoot.listSync(followLinks: false); |
| 791 var result = new Map<String, List<fileSystem.Folder>>(); | 828 var result = new Map<String, List<fileSystem.Folder>>(); |
| 792 for (var package in packages) { | 829 for (var package in packages) { |
| 793 var packageName = path.basename(package.path); | 830 var packageName = path.basename(package.path); |
| 794 var realPath = package.resolveSymbolicLinksSync(); | 831 var realPath = package.resolveSymbolicLinksSync(); |
| 795 result[packageName] = [ | 832 result[packageName] = [ |
| 796 PhysicalResourceProvider.INSTANCE.getFolder(realPath) | 833 PhysicalResourceProvider.INSTANCE.getFolder(realPath) |
| 797 ]; | 834 ]; |
| 798 } | 835 } |
| 799 return result; | 836 return result; |
| 800 } | 837 } |
| 801 } | 838 } |
| OLD | NEW |