Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(684)

Side by Side Diff: pkg/analysis_server/lib/src/context_manager.dart

Issue 914373004: Use package: URIs for files in lib (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Added test and fixed URI usage Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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:analyzer/file_system/file_system.dart'; 10 import 'package:analyzer/file_system/file_system.dart';
(...skipping 18 matching lines...) Expand all
29 */ 29 */
30 const String PUBSPEC_NAME = 'pubspec.yaml'; 30 const String PUBSPEC_NAME = 'pubspec.yaml';
31 31
32 32
33 /** 33 /**
34 * Class that maintains a mapping from included/excluded paths to a set of 34 * Class that maintains a mapping from included/excluded paths to a set of
35 * folders that should correspond to analysis contexts. 35 * folders that should correspond to analysis contexts.
36 */ 36 */
37 abstract class ContextManager { 37 abstract class ContextManager {
38 /** 38 /**
39 * The name of the `lib` directory.
40 */
41 static const String LIB_DIR_NAME = 'lib';
42
43 /**
39 * [_ContextInfo] object for each included directory in the most 44 * [_ContextInfo] object for each included directory in the most
40 * recent successful call to [setRoots]. 45 * recent successful call to [setRoots].
41 */ 46 */
42 Map<Folder, _ContextInfo> _contexts = new HashMap<Folder, _ContextInfo>(); 47 Map<Folder, _ContextInfo> _contexts = new HashMap<Folder, _ContextInfo>();
43 48
44 /** 49 /**
45 * The [ResourceProvider] using which paths are converted into [Resource]s. 50 * The [ResourceProvider] using which paths are converted into [Resource]s.
46 */ 51 */
47 final ResourceProvider resourceProvider; 52 final ResourceProvider resourceProvider;
48 53
(...skipping 29 matching lines...) Expand all
78 * Provider which is used to determine the mapping from package name to 83 * Provider which is used to determine the mapping from package name to
79 * package folder. 84 * package folder.
80 */ 85 */
81 final PackageMapProvider _packageMapProvider; 86 final PackageMapProvider _packageMapProvider;
82 87
83 ContextManager(this.resourceProvider, this._packageMapProvider) { 88 ContextManager(this.resourceProvider, this._packageMapProvider) {
84 pathContext = resourceProvider.pathContext; 89 pathContext = resourceProvider.pathContext;
85 } 90 }
86 91
87 /** 92 /**
88 * Called when a new context needs to be created. 93 * Create and return a new analysis context.
89 */ 94 */
90 void addContext(Folder folder, UriResolver packageUriResolver); 95 AnalysisContext addContext(Folder folder, UriResolver packageUriResolver);
91 96
92 /** 97 /**
93 * Called when the set of files associated with a context have changed (or 98 * Called when the set of files associated with a context have changed (or
94 * some of those files have been modified). [changeSet] is the set of 99 * some of those files have been modified). [changeSet] is the set of
95 * changes that need to be applied to the context. 100 * changes that need to be applied to the context.
96 */ 101 */
97 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet); 102 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
98 103
99 /** 104 /**
100 * We are about to start computing the package map. 105 * We are about to start computing the package map.
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 continue; 280 continue;
276 } 281 }
277 _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths); 282 _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths);
278 } 283 }
279 } 284 }
280 } 285 }
281 286
282 /** 287 /**
283 * Resursively adds all Dart and HTML files to the [changeSet]. 288 * Resursively adds all Dart and HTML files to the [changeSet].
284 */ 289 */
285 void _addSourceFiles(ChangeSet changeSet, Folder folder, _ContextInfo info) { 290 void _addSourceFiles(ChangeSet changeSet, Folder folder, _ContextInfo info,
291 bool pubspecExists, bool createPackageUri) {
286 if (info.excludesResource(folder) || folder.shortName.startsWith('.')) { 292 if (info.excludesResource(folder) || folder.shortName.startsWith('.')) {
287 return; 293 return;
288 } 294 }
289 List<Resource> children = folder.getChildren(); 295 List<Resource> children = folder.getChildren();
290 for (Resource child in children) { 296 for (Resource child in children) {
291 String path = child.path; 297 String path = child.path;
292 // ignore excluded files or folders 298 // ignore excluded files or folders
293 if (_isExcluded(path)) { 299 if (_isExcluded(path)) {
294 continue; 300 continue;
295 } 301 }
296 // add files, recurse into folders 302 // add files, recurse into folders
297 if (child is File) { 303 if (child is File) {
298 if (_shouldFileBeAnalyzed(child)) { 304 if (_shouldFileBeAnalyzed(child)) {
299 Source source = child.createSource(); 305 Source source = child.createSource();
306 if (createPackageUri) {
307 String packagePath = info.folder.path;
308 String packageName =
309 resourceProvider.pathContext.basename(packagePath);
310 String libPath =
311 resourceProvider.pathContext.join(packagePath, LIB_DIR_NAME);
312 String relPath = source.fullName.substring(libPath.length);
313 Uri uri =
314 Uri.parse('${PackageMapUriResolver.PACKAGE_SCHEME}:$packageName$ relPath');
315 source = child.createSource(uri);
316 }
300 changeSet.addedSource(source); 317 changeSet.addedSource(source);
301 info.sources[path] = source; 318 info.sources[path] = source;
302 } 319 }
303 } else if (child is Folder) { 320 } else if (child is Folder) {
304 if (child.shortName == PACKAGES_NAME) { 321 String shortName = child.shortName;
322 if (shortName == PACKAGES_NAME) {
305 continue; 323 continue;
306 } 324 }
307 _addSourceFiles(changeSet, child, info); 325 if (pubspecExists &&
326 !createPackageUri &&
327 shortName == LIB_DIR_NAME &&
328 child.parent == info.folder) {
329 _addSourceFiles(changeSet, child, info, pubspecExists, true);
330 } else {
331 _addSourceFiles(
332 changeSet,
333 child,
334 info,
335 pubspecExists,
336 createPackageUri);
337 }
308 } 338 }
309 } 339 }
310 } 340 }
311 341
312 /** 342 /**
313 * Compute the appropriate package URI resolver for [folder], and store 343 * Compute the appropriate package URI resolver for [folder], and store
314 * dependency information in [info]. Return `null` if no package map can 344 * dependency information in [info]. Return `null` if no package map can
315 * be computed. 345 * be computed.
316 */ 346 */
317 UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) { 347 UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) {
(...skipping 13 matching lines...) Expand all
331 resourceProvider, 361 resourceProvider,
332 packageMapInfo.packageMap); 362 packageMapInfo.packageMap);
333 // TODO(paulberry): if any of the dependencies is outside of [folder], 363 // TODO(paulberry): if any of the dependencies is outside of [folder],
334 // we'll need to watch their parent folders as well. 364 // we'll need to watch their parent folders as well.
335 } 365 }
336 } 366 }
337 367
338 /** 368 /**
339 * Create a new empty context associated with [folder]. 369 * Create a new empty context associated with [folder].
340 */ 370 */
341 _ContextInfo _createContext(Folder folder, List<_ContextInfo> children) { 371 _ContextInfo _createContext(Folder folder, File pubspecFile,
342 _ContextInfo info = 372 List<_ContextInfo> children) {
343 new _ContextInfo(folder, children, normalizedPackageRoots[folder.path]); 373 _ContextInfo info = new _ContextInfo(
374 folder,
375 pubspecFile,
376 children,
377 normalizedPackageRoots[folder.path]);
344 _contexts[folder] = info; 378 _contexts[folder] = info;
345 info.changeSubscription = folder.changes.listen((WatchEvent event) { 379 info.changeSubscription = folder.changes.listen((WatchEvent event) {
346 _handleWatchEvent(folder, info, event); 380 _handleWatchEvent(folder, info, event);
347 }); 381 });
348 UriResolver packageUriResolver = _computePackageUriResolver(folder, info); 382 UriResolver packageUriResolver = _computePackageUriResolver(folder, info);
349 addContext(folder, packageUriResolver); 383 info.context = addContext(folder, packageUriResolver);
350 return info; 384 return info;
351 } 385 }
352 386
353 /** 387 /**
354 * Creates a new context associated with [folder]. 388 * Creates a new context associated with [folder].
355 * 389 *
356 * If there are subfolders with 'pubspec.yaml' files, separate contexts 390 * If there are subfolders with 'pubspec.yaml' files, separate contexts
357 * are created for them, and excluded from the context associated with 391 * are created for them, and excluded from the context associated with
358 * [folder]. 392 * [folder].
359 * 393 *
360 * If [folder] itself contains a 'pubspec.yaml' file, subfolders are ignored. 394 * If [folder] itself contains a 'pubspec.yaml' file, subfolders are ignored.
361 * 395 *
362 * If [withPubspecOnly] is `true`, a context will be created only if there 396 * If [withPubspecOnly] is `true`, a context will be created only if there
363 * is a 'pubspec.yaml' file in [folder]. 397 * is a 'pubspec.yaml' file in [folder].
364 * 398 *
365 * Returns create pubspec-based contexts. 399 * Returns create pubspec-based contexts.
366 */ 400 */
367 List<_ContextInfo> _createContexts(Folder folder, bool withPubspecOnly) { 401 List<_ContextInfo> _createContexts(Folder folder, bool withPubspecOnly) {
368 // check if there is a pubspec in the folder 402 // check whether there is a pubspec in the folder
369 { 403 File pubspecFile = folder.getChild(PUBSPEC_NAME);
370 File pubspecFile = folder.getChild(PUBSPEC_NAME); 404 bool pubspecExists = pubspecFile.exists;
371 if (pubspecFile.exists) { 405 if (pubspecExists) {
372 _ContextInfo info = _createContextWithSources(folder, <_ContextInfo>[]); 406 _ContextInfo info = _createContextWithSources(
373 return [info]; 407 folder,
374 } 408 pubspecFile,
409 pubspecExists,
410 <_ContextInfo>[]);
411 return [info];
375 } 412 }
376 // try to find subfolders with pubspec files 413 // try to find subfolders with pubspec files
377 List<_ContextInfo> children = <_ContextInfo>[]; 414 List<_ContextInfo> children = <_ContextInfo>[];
378 for (Resource child in folder.getChildren()) { 415 for (Resource child in folder.getChildren()) {
379 if (child is Folder) { 416 if (child is Folder) {
380 List<_ContextInfo> childContexts = _createContexts(child, true); 417 List<_ContextInfo> childContexts = _createContexts(child, true);
381 children.addAll(childContexts); 418 children.addAll(childContexts);
382 } 419 }
383 } 420 }
384 // no pubspec, done 421 // no pubspec, done
385 if (withPubspecOnly) { 422 if (withPubspecOnly) {
386 return children; 423 return children;
387 } 424 }
388 // OK, create a context without a pubspec 425 // OK, create a context without a pubspec
389 _createContextWithSources(folder, children); 426 _createContextWithSources(folder, pubspecFile, pubspecExists, children);
390 return children; 427 return children;
391 } 428 }
392 429
393 /** 430 /**
394 * Create a new context associated with [folder] and fills its with sources. 431 * Create a new context associated with the given [folder]. The [pubspecFile]
432 * is the `pubspec.yaml` file contained in the folder, and [pubspecExists] is
433 * `true` if the file exists. Add any sources that are not included in one of
434 * the [children] to the context.
395 */ 435 */
396 _ContextInfo _createContextWithSources(Folder folder, 436 _ContextInfo _createContextWithSources(Folder folder, File pubspecFile,
397 List<_ContextInfo> children) { 437 bool pubspecExists, List<_ContextInfo> children) {
398 _ContextInfo info = _createContext(folder, children); 438 _ContextInfo info = _createContext(folder, pubspecFile, children);
399 ChangeSet changeSet = new ChangeSet(); 439 ChangeSet changeSet = new ChangeSet();
400 _addSourceFiles(changeSet, folder, info); 440 _addSourceFiles(changeSet, folder, info, pubspecExists, false);
401 applyChangesToContext(folder, changeSet); 441 applyChangesToContext(folder, changeSet);
402 return info; 442 return info;
403 } 443 }
404 444
405 /** 445 /**
406 * Clean up and destroy the context associated with the given folder. 446 * Clean up and destroy the context associated with the given folder.
407 */ 447 */
408 void _destroyContext(Folder folder) { 448 void _destroyContext(Folder folder) {
409 _contexts[folder].changeSubscription.cancel(); 449 _contexts[folder].changeSubscription.cancel();
410 _contexts.remove(folder); 450 _contexts.remove(folder);
411 removeContext(folder); 451 removeContext(folder);
412 } 452 }
413 453
414 /** 454 /**
415 * Extract a new [pubspecFile]-based context from [oldInfo]. 455 * Extract a new [pubspecFile]-based context from [oldInfo].
416 */ 456 */
417 void _extractContext(_ContextInfo oldInfo, File pubspecFile) { 457 void _extractContext(_ContextInfo oldInfo, File pubspecFile) {
418 Folder newFolder = pubspecFile.parent; 458 Folder newFolder = pubspecFile.parent;
419 _ContextInfo newInfo = _createContext(newFolder, []); 459 _ContextInfo newInfo = _createContext(newFolder, pubspecFile, []);
420 newInfo.parent = oldInfo; 460 newInfo.parent = oldInfo;
421 // prepare sources to extract 461 // prepare sources to extract
422 Map<String, Source> extractedSources = new HashMap<String, Source>(); 462 Map<String, Source> extractedSources = new HashMap<String, Source>();
423 oldInfo.sources.forEach((path, source) { 463 oldInfo.sources.forEach((path, source) {
424 if (newFolder.contains(path)) { 464 if (newFolder.contains(path)) {
425 extractedSources[path] = source; 465 extractedSources[path] = source;
426 } 466 }
427 }); 467 });
428 // update new context 468 // update new context
429 { 469 {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 */ 662 */
623 String pubspecPath; 663 String pubspecPath;
624 664
625 /** 665 /**
626 * Stream subscription we are using to watch the context's directory for 666 * Stream subscription we are using to watch the context's directory for
627 * changes. 667 * changes.
628 */ 668 */
629 StreamSubscription<WatchEvent> changeSubscription; 669 StreamSubscription<WatchEvent> changeSubscription;
630 670
631 /** 671 /**
672 * The analysis context that was created for the [folder].
673 */
674 AnalysisContext context;
675
676 /**
632 * Map from full path to the [Source] object, for each source that has been 677 * Map from full path to the [Source] object, for each source that has been
633 * added to the context. 678 * added to the context.
634 */ 679 */
635 Map<String, Source> sources = new HashMap<String, Source>(); 680 Map<String, Source> sources = new HashMap<String, Source>();
636 681
637 /** 682 /**
638 * Dependencies of the context's package map. 683 * Dependencies of the context's package map.
639 * If any of these files changes, the package map needs to be recomputed. 684 * If any of these files changes, the package map needs to be recomputed.
640 */ 685 */
641 Set<String> packageMapDependencies; 686 Set<String> packageMapDependencies;
642 687
643 _ContextInfo(this.folder, this.children, this.packageRoot) { 688 _ContextInfo(this.folder, File pubspecFile, this.children, this.packageRoot) {
644 pubspecPath = folder.getChild(PUBSPEC_NAME).path; 689 pubspecPath = pubspecFile.path;
645 for (_ContextInfo child in children) { 690 for (_ContextInfo child in children) {
646 child.parent = this; 691 child.parent = this;
647 } 692 }
648 } 693 }
649 694
650 /** 695 /**
651 * Returns `true` if this context is root folder based. 696 * Returns `true` if this context is root folder based.
652 */ 697 */
653 bool get isRoot => parent == null; 698 bool get isRoot => parent == null;
654 699
(...skipping 13 matching lines...) Expand all
668 return excludes(resource.path); 713 return excludes(resource.path);
669 } 714 }
670 715
671 /** 716 /**
672 * Returns `true` if [path] is the pubspec file of this context. 717 * Returns `true` if [path] is the pubspec file of this context.
673 */ 718 */
674 bool isPubspec(String path) { 719 bool isPubspec(String path) {
675 return path == pubspecPath; 720 return path == pubspecPath;
676 } 721 }
677 } 722 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/analysis_server.dart ('k') | pkg/analysis_server/test/context_manager_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698