Linter Demo Errors: 0Warnings: 9File: /home/fstrocco/Dart/dart/benchmark/analyzer/lib/source/pub_package_map_provider.dart // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library source.pub_package_map_provider; import 'dart:collection'; import 'dart:convert'; import 'dart:io' as io; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/source/package_map_provider.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/sdk_io.dart'; /** * The function used to run pub list. */ typedef io.ProcessResult RunPubList(Folder folder); /** * Implementation of PackageMapProvider that operates by executing pub. */ class PubPackageMapProvider implements PackageMapProvider { static const String PUB_LIST_COMMAND = 'list-package-dirs'; /** * The name of the 'pubspec.lock' file, which we assume is the dependency * in the event that [PUB_LIST_COMMAND] fails. */ static const String PUBSPEC_LOCK_NAME = 'pubspec.lock'; /** * [ResourceProvider] that is used to create the [Folder]s that populate the * package map. */ final ResourceProvider resourceProvider; /** * Sdk that we use to find the pub executable. */ final DirectoryBasedDartSdk sdk; /** * The function used to run pub list. */ RunPubList _runPubList; /** * Construct a new instance. * A [RunPubList] implementation may be injected for testing */ PubPackageMapProvider(this.resourceProvider, this.sdk, [this._runPubList]) { if (_runPubList == null) { _runPubList = _runPubListDefault; } } @override PackageMapInfo computePackageMap(Folder folder) { // TODO(paulberry) make this asynchronous so that we can (a) do other // analysis while it's in progress, and (b) time out if it takes too long // to respond. io.ProcessResult result; try { result = _runPubList(folder); } on io.ProcessException catch (exception, stackTrace) { AnalysisEngine.instance.logger.logInformation( "Error running pub $PUB_LIST_COMMAND\n$exception\n$stackTrace"); } if (result == null || result.exitCode != 0) { String exitCode = result != null ? 'exit code ${result.exitCode}' : 'null'; AnalysisEngine.instance.logger .logInformation("pub $PUB_LIST_COMMAND failed: $exitCode"); return computePackageMapError(folder); } try { PackageMapInfo packageMap = parsePackageMap(JSON.decode(result.stdout), folder); return packageMap; } catch (exception, stackTrace) { AnalysisEngine.instance.logger.logError( "Malformed output from pub $PUB_LIST_COMMAND\n$exception\n$stackTrace"); } return computePackageMapError(folder); } /** * Create a PackageMapInfo object representing an error condition. */ PackageMapInfo computePackageMapError(Folder folder) { // Even if an error occurs, we still need to know the dependencies, so that // we'll know when to try running "pub list-package-dirs" again. // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when // an error occurs, so just assume there is one dependency, "pubspec.lock". List dependencies = [ resourceProvider.pathContext.join(folder.path, PUBSPEC_LOCK_NAME) ]; return new PackageMapInfo(null, dependencies.toSet()); } /** * Decode the JSON output from pub into a package map. Paths in the * output are considered relative to [folder]. */ PackageMapInfo parsePackageMap(Map obj, Folder folder) { // The output of pub looks like this: // { // "packages": { // "foo": "path/to/foo", // "bar": ["path/to/bar1", "path/to/bar2"], // "myapp": "path/to/myapp", // self link is included // }, // "input_files": [ // "path/to/myapp/pubspec.lock" // ] // } Map> packageMap = new HashMap>(); Map packages = obj['packages']; processPaths(String packageName, List paths) { List folders = []; for (var path in paths) { if (path is String) { Resource resource = folder.getChildAssumingFolder(path); if (resource is Folder) { folders.add(resource); } } } if (folders.isNotEmpty) { packageMap[packageName] = folders; } } packages.forEach((key, value) { if (value is String) { processPaths(key, [value]); } else if (value is List) { processPaths(key, value); } }); Set dependencies = new Set(); List inputFiles = obj['input_files']; if (inputFiles != null) { for (var path in inputFiles) { if (path is String) { dependencies.add(folder.canonicalizePath(path)); } } } return new PackageMapInfo(packageMap, dependencies); } /** * Run pub list to determine the packages and input files. */ io.ProcessResult _runPubListDefault(Folder folder) { return io.Process.runSync(sdk.pubExecutable.getAbsolutePath(), [ PUB_LIST_COMMAND ], workingDirectory: folder.path); } }