| 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 context.directory.manager; | 5 library context.directory.manager; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:analysis_server/src/package_map_provider.dart'; | 10 import 'package:analysis_server/src/package_map_provider.dart'; |
| 11 import 'package:analyzer/file_system/file_system.dart'; | 11 import 'package:analyzer/file_system/file_system.dart'; |
| 12 import 'package:analyzer/src/generated/engine.dart'; | 12 import 'package:analyzer/src/generated/engine.dart'; |
| 13 import 'package:analyzer/src/generated/source.dart'; | 13 import 'package:analyzer/src/generated/source.dart'; |
| 14 import 'package:path/path.dart' as pathos; | 14 import 'package:path/path.dart' as pathos; |
| 15 import 'package:watcher/watcher.dart'; | 15 import 'package:watcher/watcher.dart'; |
| 16 | 16 |
| 17 | 17 |
| 18 /** | 18 /** |
| 19 * File name of pubspec files. | 19 * File name of pubspec files. |
| 20 */ | 20 */ |
| 21 const String PUBSPEC_NAME = 'pubspec.yaml'; | 21 const String PUBSPEC_NAME = 'pubspec.yaml'; |
| 22 | 22 |
| 23 | 23 |
| 24 /** | 24 /** |
| 25 * The name of `packages` folders. |
| 26 */ |
| 27 const String PACKAGES_NAME = 'packages'; |
| 28 |
| 29 |
| 30 /** |
| 25 * Class that maintains a mapping from included/excluded paths to a set of | 31 * Class that maintains a mapping from included/excluded paths to a set of |
| 26 * folders that should correspond to analysis contexts. | 32 * folders that should correspond to analysis contexts. |
| 27 */ | 33 */ |
| 28 abstract class ContextManager { | 34 abstract class ContextManager { |
| 29 /** | 35 /** |
| 30 * [_ContextInfo] object for each included directory in the most | 36 * [_ContextInfo] object for each included directory in the most |
| 31 * recent successful call to [setRoots]. | 37 * recent successful call to [setRoots]. |
| 32 */ | 38 */ |
| 33 Map<Folder, _ContextInfo> _contexts = new HashMap<Folder, _ContextInfo>(); | 39 Map<Folder, _ContextInfo> _contexts = new HashMap<Folder, _ContextInfo>(); |
| 34 | 40 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 continue; | 191 continue; |
| 186 } | 192 } |
| 187 // add files, recurse into folders | 193 // add files, recurse into folders |
| 188 if (child is File) { | 194 if (child is File) { |
| 189 if (_shouldFileBeAnalyzed(child)) { | 195 if (_shouldFileBeAnalyzed(child)) { |
| 190 Source source = child.createSource(); | 196 Source source = child.createSource(); |
| 191 changeSet.addedSource(source); | 197 changeSet.addedSource(source); |
| 192 info.sources[path] = source; | 198 info.sources[path] = source; |
| 193 } | 199 } |
| 194 } else if (child is Folder) { | 200 } else if (child is Folder) { |
| 195 if (child.shortName == 'packages') { | 201 if (child.shortName == PACKAGES_NAME) { |
| 196 // TODO(paulberry): perhaps we should only skip packages dirs if | |
| 197 // there is a pubspec.yaml? | |
| 198 continue; | 202 continue; |
| 199 } | 203 } |
| 200 _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths); | 204 _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths); |
| 201 } | 205 } |
| 202 } | 206 } |
| 203 } | 207 } |
| 204 | 208 |
| 205 /** | 209 /** |
| 206 * Resursively adds all Dart and HTML files to the [changeSet]. | 210 * Resursively adds all Dart and HTML files to the [changeSet]. |
| 207 */ | 211 */ |
| 208 void _addSourceFiles(ChangeSet changeSet, Folder folder, _ContextInfo info) { | 212 void _addSourceFiles(ChangeSet changeSet, Folder folder, _ContextInfo info) { |
| 209 if (info.excludesResource(folder)) { | 213 if (info.excludesResource(folder)) { |
| 210 return; | 214 return; |
| 211 } | 215 } |
| 212 List<Resource> children = folder.getChildren(); | 216 List<Resource> children = folder.getChildren(); |
| 213 for (Resource child in children) { | 217 for (Resource child in children) { |
| 214 String path = child.path; | 218 String path = child.path; |
| 215 // ignore excluded files or folders | 219 // ignore excluded files or folders |
| 216 if (_isExcluded(path)) { | 220 if (_isExcluded(path)) { |
| 217 continue; | 221 continue; |
| 218 } | 222 } |
| 219 // add files, recurse into folders | 223 // add files, recurse into folders |
| 220 if (child is File) { | 224 if (child is File) { |
| 221 if (_shouldFileBeAnalyzed(child)) { | 225 if (_shouldFileBeAnalyzed(child)) { |
| 222 Source source = child.createSource(); | 226 Source source = child.createSource(); |
| 223 changeSet.addedSource(source); | 227 changeSet.addedSource(source); |
| 224 info.sources[path] = source; | 228 info.sources[path] = source; |
| 225 } | 229 } |
| 226 } else if (child is Folder) { | 230 } else if (child is Folder) { |
| 227 if (child.shortName == 'packages') { | 231 if (child.shortName == PACKAGES_NAME) { |
| 228 // TODO(paulberry): perhaps we should only skip packages dirs if | |
| 229 // there is a pubspec.yaml? | |
| 230 continue; | 232 continue; |
| 231 } | 233 } |
| 232 _addSourceFiles(changeSet, child, info); | 234 _addSourceFiles(changeSet, child, info); |
| 233 } | 235 } |
| 234 } | 236 } |
| 235 } | 237 } |
| 236 | 238 |
| 237 /** | 239 /** |
| 238 * Create a new empty context associated with [folder]. | 240 * Create a new empty context associated with [folder]. |
| 239 */ | 241 */ |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 return; | 356 return; |
| 355 } | 357 } |
| 356 // maybe excluded from the context, so other context will handle it | 358 // maybe excluded from the context, so other context will handle it |
| 357 if (info.excludes(path)) { | 359 if (info.excludes(path)) { |
| 358 return; | 360 return; |
| 359 } | 361 } |
| 360 // handle the change | 362 // handle the change |
| 361 switch (event.type) { | 363 switch (event.type) { |
| 362 case ChangeType.ADD: | 364 case ChangeType.ADD: |
| 363 if (_isInPackagesDir(path, folder)) { | 365 if (_isInPackagesDir(path, folder)) { |
| 364 // TODO(paulberry): perhaps we should only skip packages dirs if | 366 return; |
| 365 // there is a pubspec.yaml? | |
| 366 break; | |
| 367 } | 367 } |
| 368 Resource resource = resourceProvider.getResource(path); | 368 Resource resource = resourceProvider.getResource(path); |
| 369 // pubspec was added in a sub-folder, extract a new context | 369 // pubspec was added in a sub-folder, extract a new context |
| 370 if (_isPubspec(path) && info.isRoot && !info.isPubspec(path)) { | 370 if (_isPubspec(path) && info.isRoot && !info.isPubspec(path)) { |
| 371 _extractContext(info, resource); | 371 _extractContext(info, resource); |
| 372 return; | 372 return; |
| 373 } | 373 } |
| 374 // If the file went away and was replaced by a folder before we | 374 // If the file went away and was replaced by a folder before we |
| 375 // had a chance to process the event, resource might be a Folder. In | 375 // had a chance to process the event, resource might be a Folder. In |
| 376 // that case don't add it. | 376 // that case don't add it. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 }); | 440 }); |
| 441 } | 441 } |
| 442 | 442 |
| 443 /** | 443 /** |
| 444 * Determine if the path from [folder] to [path] contains a 'packages' | 444 * Determine if the path from [folder] to [path] contains a 'packages' |
| 445 * directory. | 445 * directory. |
| 446 */ | 446 */ |
| 447 bool _isInPackagesDir(String path, Folder folder) { | 447 bool _isInPackagesDir(String path, Folder folder) { |
| 448 String relativePath = pathContext.relative(path, from: folder.path); | 448 String relativePath = pathContext.relative(path, from: folder.path); |
| 449 List<String> pathParts = pathContext.split(relativePath); | 449 List<String> pathParts = pathContext.split(relativePath); |
| 450 for (int i = 0; i < pathParts.length - 1; i++) { | 450 return pathParts.contains(PACKAGES_NAME); |
| 451 if (pathParts[i] == 'packages') { | |
| 452 return true; | |
| 453 } | |
| 454 } | |
| 455 return false; | |
| 456 } | 451 } |
| 457 | 452 |
| 458 /** | 453 /** |
| 459 * Returns `true` if the given absolute [path] is a pubspec file. | 454 * Returns `true` if the given absolute [path] is a pubspec file. |
| 460 */ | 455 */ |
| 461 bool _isPubspec(String path) { | 456 bool _isPubspec(String path) { |
| 462 return pathContext.basename(path) == PUBSPEC_NAME; | 457 return pathContext.basename(path) == PUBSPEC_NAME; |
| 463 } | 458 } |
| 464 | 459 |
| 465 /** | 460 /** |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 return excludes(resource.path); | 560 return excludes(resource.path); |
| 566 } | 561 } |
| 567 | 562 |
| 568 /** | 563 /** |
| 569 * Returns `true` if [path] is the pubspec file of this context. | 564 * Returns `true` if [path] is the pubspec file of this context. |
| 570 */ | 565 */ |
| 571 bool isPubspec(String path) { | 566 bool isPubspec(String path) { |
| 572 return path == pubspecPath; | 567 return path == pubspecPath; |
| 573 } | 568 } |
| 574 } | 569 } |
| OLD | NEW |