Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 package.map.provider; | 5 library package.map.provider; |
| 6 | 6 |
| 7 import 'dart:convert'; | 7 import 'dart:convert'; |
| 8 import 'dart:io' as io; | 8 import 'dart:io' as io; |
| 9 | 9 |
| 10 import 'package:analysis_server/src/analysis_server.dart'; | 10 import 'package:analysis_server/src/analysis_server.dart'; |
| 11 import 'package:analysis_server/src/resource.dart'; | 11 import 'package:analysis_server/src/resource.dart'; |
| 12 import 'package:analyzer/src/generated/engine.dart'; | 12 import 'package:analyzer/src/generated/engine.dart'; |
| 13 | 13 |
| 14 /** | 14 /** |
| 15 * A PackageMapProvider is an entity capable of determining the mapping from | 15 * A PackageMapProvider is an entity capable of determining the mapping from |
| 16 * package name to source directory for a given folder. | 16 * package name to source directory for a given folder. |
| 17 */ | 17 */ |
| 18 abstract class PackageMapProvider { | 18 abstract class PackageMapProvider { |
| 19 /** | 19 /** |
| 20 * Compute a package map for the given folder, if possible. | 20 * Compute a package map for the given folder, if possible. |
| 21 * | 21 * |
| 22 * If a package map can't be computed, return null. | 22 * If a package map can't be computed, return null. |
| 23 */ | 23 */ |
| 24 Map<String, Folder> computePackageMap(Folder folder); | 24 Map<String, List<Folder>> computePackageMap(Folder folder); |
| 25 } | 25 } |
| 26 | 26 |
| 27 /** | 27 /** |
| 28 * Implementation of PackageMapProvider that operates by executing pub. | 28 * Implementation of PackageMapProvider that operates by executing pub. |
| 29 */ | 29 */ |
| 30 class PubPackageMapProvider implements PackageMapProvider { | 30 class PubPackageMapProvider implements PackageMapProvider { |
| 31 static const String PUB_LIST_COMMAND = 'list-package-dirs'; | 31 static const String PUB_LIST_COMMAND = 'list-package-dirs'; |
| 32 | 32 |
| 33 /** | 33 /** |
| 34 * [ResourceProvider] that is used to create the [Folder]s that populate the | 34 * [ResourceProvider] that is used to create the [Folder]s that populate the |
| 35 * package map. | 35 * package map. |
| 36 */ | 36 */ |
| 37 final ResourceProvider resourceProvider; | 37 final ResourceProvider resourceProvider; |
| 38 | 38 |
| 39 PubPackageMapProvider(this.resourceProvider); | 39 PubPackageMapProvider(this.resourceProvider); |
| 40 | 40 |
| 41 @override | 41 @override |
| 42 Map<String, Folder> computePackageMap(Folder folder) { | 42 Map<String, List<Folder>> computePackageMap(Folder folder) { |
| 43 // TODO(paulberry) make this asynchronous so that we can (a) do other | 43 // TODO(paulberry) make this asynchronous so that we can (a) do other |
| 44 // analysis while it's in progress, and (b) time out if it takes too long | 44 // analysis while it's in progress, and (b) time out if it takes too long |
| 45 // to respond. | 45 // to respond. |
| 46 String executable = SHARED_SDK.pubExecutable.getAbsolutePath(); | 46 String executable = SHARED_SDK.pubExecutable.getAbsolutePath(); |
| 47 io.ProcessResult result; | 47 io.ProcessResult result; |
| 48 try { | 48 try { |
| 49 result = io.Process.runSync( | 49 result = io.Process.runSync( |
| 50 executable, [PUB_LIST_COMMAND], workingDirectory: folder.path); | 50 executable, [PUB_LIST_COMMAND], workingDirectory: folder.path); |
| 51 } on io.ProcessException catch (exception, stackTrace) { | 51 } on io.ProcessException catch (exception, stackTrace) { |
| 52 AnalysisEngine.instance.logger.logInformation( | 52 AnalysisEngine.instance.logger.logInformation( |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 63 AnalysisEngine.instance.logger.logError( | 63 AnalysisEngine.instance.logger.logError( |
| 64 "Malformed output from pub $PUB_LIST_COMMAND\n${exception}\n${stackTra ce}"); | 64 "Malformed output from pub $PUB_LIST_COMMAND\n${exception}\n${stackTra ce}"); |
| 65 } | 65 } |
| 66 | 66 |
| 67 return null; | 67 return null; |
| 68 } | 68 } |
| 69 | 69 |
| 70 /** | 70 /** |
| 71 * Decode the JSON output from pub into a package map. | 71 * Decode the JSON output from pub into a package map. |
| 72 */ | 72 */ |
| 73 Map<String, Folder> parsePackageMap(String jsonText) { | 73 Map<String, List<Folder>> parsePackageMap(String jsonText) { |
| 74 // The output of pub looks like this: | 74 // The output of pub looks like this: |
| 75 // { | 75 // { |
| 76 // "packages": { | 76 // "packages": { |
| 77 // "foo": "path/to/foo", | 77 // "foo": "path/to/foo", |
| 78 // "bar": ["path/to/bar1", "path/to/bar2"], | 78 // "bar": ["path/to/bar1", "path/to/bar2"], |
| 79 // "myapp": "path/to/myapp", // self link is included | 79 // "myapp": "path/to/myapp", // self link is included |
| 80 // }, | 80 // }, |
| 81 // "input_files": [ | 81 // "input_files": [ |
| 82 // "path/to/myapp/pubspec.lock" | 82 // "path/to/myapp/pubspec.lock" |
| 83 // ] | 83 // ] |
| 84 // } | 84 // } |
| 85 Map<String, Folder> packageMap = <String, Folder>{}; | 85 Map<String, List<Folder>> packageMap = <String, List<Folder>>{}; |
| 86 Map obj = JSON.decode(jsonText); | 86 Map obj = JSON.decode(jsonText); |
| 87 Map packages = obj['packages']; | 87 Map packages = obj['packages']; |
| 88 processPaths(String packageName, List paths) { | |
| 89 List<Folder> folders = <Folder>[]; | |
| 90 for (var path in paths) { | |
| 91 if (path is String) { | |
| 92 Resource resource = resourceProvider.getResource(path); | |
| 93 if (resource is Folder) { | |
| 94 folders.add(resource); | |
| 95 } | |
| 96 if (folders.isNotEmpty) { | |
|
scheglov
2014/06/20 20:06:59
Move this out of the "paths" loop?
Paul Berry
2014/06/20 20:12:33
Oops, you're right. Fixed.
| |
| 97 packageMap[packageName] = folders; | |
| 98 } | |
| 99 } | |
| 100 } | |
| 101 } | |
| 88 packages.forEach((key, value) { | 102 packages.forEach((key, value) { |
| 89 if (value is String) { | 103 if (value is String) { |
| 90 Resource resource = resourceProvider.getResource(value); | 104 processPaths(key, [value]); |
| 91 if (resource is Folder) { | |
| 92 packageMap[key] = resource; | |
| 93 } | |
| 94 } else if (value is List) { | 105 } else if (value is List) { |
| 95 // TODO(paulberry): support string lists. | 106 processPaths(key, value); |
| 96 } | 107 } |
| 97 }); | 108 }); |
| 98 return packageMap; | 109 return packageMap; |
| 99 } | 110 } |
| 100 } | 111 } |
| OLD | NEW |