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

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

Issue 946803002: Create package: URIs everywhere (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 continue; 265 continue;
266 } 266 }
267 // ignore if was not excluded 267 // ignore if was not excluded
268 bool wasExcluded = 268 bool wasExcluded =
269 _isExcludedBy(oldExcludedPaths, path) && 269 _isExcludedBy(oldExcludedPaths, path) &&
270 !_isExcludedBy(excludedPaths, path); 270 !_isExcludedBy(excludedPaths, path);
271 if (!wasExcluded) { 271 if (!wasExcluded) {
272 continue; 272 continue;
273 } 273 }
274 // do add the file 274 // do add the file
275 Source source = child.createSource(); 275 Source source = createSourceInContext(info.context, child);
276 changeSet.addedSource(source); 276 changeSet.addedSource(source);
277 info.sources[path] = source; 277 info.sources[path] = source;
278 } else if (child is Folder) { 278 } else if (child is Folder) {
279 if (child.shortName == PACKAGES_NAME) { 279 if (child.shortName == PACKAGES_NAME) {
280 continue; 280 continue;
281 } 281 }
282 _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths); 282 _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths);
283 } 283 }
284 } 284 }
285 } 285 }
286 286
287 /** 287 /**
288 * Resursively adds all Dart and HTML files to the [changeSet]. 288 * Resursively adds all Dart and HTML files to the [changeSet].
289 */ 289 */
290 void _addSourceFiles(ChangeSet changeSet, Folder folder, _ContextInfo info, 290 void _addSourceFiles(ChangeSet changeSet, Folder folder, _ContextInfo info) {
291 bool pubspecExists, bool createPackageUri) {
292 if (info.excludesResource(folder) || folder.shortName.startsWith('.')) { 291 if (info.excludesResource(folder) || folder.shortName.startsWith('.')) {
293 return; 292 return;
294 } 293 }
295 List<Resource> children = folder.getChildren(); 294 List<Resource> children = folder.getChildren();
296 for (Resource child in children) { 295 for (Resource child in children) {
297 String path = child.path; 296 String path = child.path;
298 // ignore excluded files or folders 297 // ignore excluded files or folders
299 if (_isExcluded(path)) { 298 if (_isExcluded(path)) {
300 continue; 299 continue;
301 } 300 }
302 // add files, recurse into folders 301 // add files, recurse into folders
303 if (child is File) { 302 if (child is File) {
304 if (_shouldFileBeAnalyzed(child)) { 303 if (_shouldFileBeAnalyzed(child)) {
305 Source source = child.createSource(); 304 Source source = createSourceInContext(info.context, child);
306 if (createPackageUri) {
307 //
308 // It should be possible to generate the uri by executing:
309 //
310 // Uri uri = info.context.sourceFactory.restoreUri(source);
311 //
312 // but for some reason this doesn't produce the same result as the
313 // code below. This needs to be investigated.
314 // (See https://code.google.com/p/dart/issues/detail?id=22463).
315 //
316 String packagePath = info.folder.path;
317 String packageName =
318 resourceProvider.pathContext.basename(packagePath);
319 String libPath =
320 resourceProvider.pathContext.join(packagePath, LIB_DIR_NAME);
321 String relPath = source.fullName.substring(libPath.length);
322 Uri uri =
323 Uri.parse('${PackageMapUriResolver.PACKAGE_SCHEME}:$packageName$ relPath');
324 source = child.createSource(uri);
325 }
326 changeSet.addedSource(source); 305 changeSet.addedSource(source);
327 info.sources[path] = source; 306 info.sources[path] = source;
328 } 307 }
329 } else if (child is Folder) { 308 } else if (child is Folder) {
330 String shortName = child.shortName; 309 String shortName = child.shortName;
331 if (shortName == PACKAGES_NAME) { 310 if (shortName == PACKAGES_NAME) {
332 continue; 311 continue;
333 } 312 }
334 if (pubspecExists && 313 _addSourceFiles(changeSet, child, info);
335 !createPackageUri &&
336 shortName == LIB_DIR_NAME &&
337 child.parent == info.folder) {
338 _addSourceFiles(changeSet, child, info, pubspecExists, true);
339 } else {
340 _addSourceFiles(
341 changeSet,
342 child,
343 info,
344 pubspecExists,
345 createPackageUri);
346 }
347 } 314 }
348 } 315 }
349 } 316 }
350 317
351 /** 318 /**
352 * Compute the appropriate package URI resolver for [folder], and store 319 * Compute the appropriate package URI resolver for [folder], and store
353 * dependency information in [info]. Return `null` if no package map can 320 * dependency information in [info]. Return `null` if no package map can
354 * be computed. 321 * be computed.
355 */ 322 */
356 UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) { 323 UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) {
(...skipping 30 matching lines...) Expand all
387 _contexts[folder] = info; 354 _contexts[folder] = info;
388 info.changeSubscription = folder.changes.listen((WatchEvent event) { 355 info.changeSubscription = folder.changes.listen((WatchEvent event) {
389 _handleWatchEvent(folder, info, event); 356 _handleWatchEvent(folder, info, event);
390 }); 357 });
391 UriResolver packageUriResolver = _computePackageUriResolver(folder, info); 358 UriResolver packageUriResolver = _computePackageUriResolver(folder, info);
392 info.context = addContext(folder, packageUriResolver); 359 info.context = addContext(folder, packageUriResolver);
393 return info; 360 return info;
394 } 361 }
395 362
396 /** 363 /**
364 * Create a new context associated with the given [folder]. The [pubspecFile]
365 * is the `pubspec.yaml` file contained in the folder. Add any sources that
366 * are not included in one of the [children] to the context.
367 */
368 _ContextInfo _createContextWithSources(Folder folder, File pubspecFile,
369 List<_ContextInfo> children) {
370 _ContextInfo info = _createContext(folder, pubspecFile, children);
371 ChangeSet changeSet = new ChangeSet();
372 _addSourceFiles(changeSet, folder, info);
373 applyChangesToContext(folder, changeSet);
374 return info;
375 }
376
377 /**
397 * Creates a new context associated with [folder]. 378 * Creates a new context associated with [folder].
398 * 379 *
399 * If there are subfolders with 'pubspec.yaml' files, separate contexts 380 * If there are subfolders with 'pubspec.yaml' files, separate contexts
400 * are created for them, and excluded from the context associated with 381 * are created for them, and excluded from the context associated with
401 * [folder]. 382 * [folder].
402 * 383 *
403 * If [folder] itself contains a 'pubspec.yaml' file, subfolders are ignored. 384 * If [folder] itself contains a 'pubspec.yaml' file, subfolders are ignored.
404 * 385 *
405 * If [withPubspecOnly] is `true`, a context will be created only if there 386 * If [withPubspecOnly] is `true`, a context will be created only if there
406 * is a 'pubspec.yaml' file in [folder]. 387 * is a 'pubspec.yaml' file in [folder].
407 * 388 *
408 * Returns create pubspec-based contexts. 389 * Returns create pubspec-based contexts.
409 */ 390 */
410 List<_ContextInfo> _createContexts(Folder folder, bool withPubspecOnly) { 391 List<_ContextInfo> _createContexts(Folder folder, bool withPubspecOnly) {
411 // check whether there is a pubspec in the folder 392 // check whether there is a pubspec in the folder
412 File pubspecFile = folder.getChild(PUBSPEC_NAME); 393 File pubspecFile = folder.getChild(PUBSPEC_NAME);
413 bool pubspecExists = pubspecFile.exists; 394 if (pubspecFile.exists) {
414 if (pubspecExists) { 395 _ContextInfo info =
415 _ContextInfo info = _createContextWithSources( 396 _createContextWithSources(folder, pubspecFile, <_ContextInfo>[]);
416 folder,
417 pubspecFile,
418 pubspecExists,
419 <_ContextInfo>[]);
420 return [info]; 397 return [info];
421 } 398 }
422 // try to find subfolders with pubspec files 399 // try to find subfolders with pubspec files
423 List<_ContextInfo> children = <_ContextInfo>[]; 400 List<_ContextInfo> children = <_ContextInfo>[];
424 for (Resource child in folder.getChildren()) { 401 for (Resource child in folder.getChildren()) {
425 if (child is Folder) { 402 if (child is Folder) {
426 List<_ContextInfo> childContexts = _createContexts(child, true); 403 List<_ContextInfo> childContexts = _createContexts(child, true);
427 children.addAll(childContexts); 404 children.addAll(childContexts);
428 } 405 }
429 } 406 }
430 // no pubspec, done 407 // no pubspec, done
431 if (withPubspecOnly) { 408 if (withPubspecOnly) {
432 return children; 409 return children;
433 } 410 }
434 // OK, create a context without a pubspec 411 // OK, create a context without a pubspec
435 _createContextWithSources(folder, pubspecFile, pubspecExists, children); 412 _createContextWithSources(folder, pubspecFile, children);
436 return children; 413 return children;
437 } 414 }
438 415
439 /** 416 /**
440 * Create a new context associated with the given [folder]. The [pubspecFile]
441 * is the `pubspec.yaml` file contained in the folder, and [pubspecExists] is
442 * `true` if the file exists. Add any sources that are not included in one of
443 * the [children] to the context.
444 */
445 _ContextInfo _createContextWithSources(Folder folder, File pubspecFile,
446 bool pubspecExists, List<_ContextInfo> children) {
447 _ContextInfo info = _createContext(folder, pubspecFile, children);
448 ChangeSet changeSet = new ChangeSet();
449 _addSourceFiles(changeSet, folder, info, pubspecExists, false);
450 applyChangesToContext(folder, changeSet);
451 return info;
452 }
453
454 /**
455 * Clean up and destroy the context associated with the given folder. 417 * Clean up and destroy the context associated with the given folder.
456 */ 418 */
457 void _destroyContext(Folder folder) { 419 void _destroyContext(Folder folder) {
458 _contexts[folder].changeSubscription.cancel(); 420 _contexts[folder].changeSubscription.cancel();
459 _contexts.remove(folder); 421 _contexts.remove(folder);
460 removeContext(folder); 422 removeContext(folder);
461 } 423 }
462 424
463 /** 425 /**
464 * Extract a new [pubspecFile]-based context from [oldInfo]. 426 * Extract a new [pubspecFile]-based context from [oldInfo].
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 _extractContext(info, resource); 478 _extractContext(info, resource);
517 return; 479 return;
518 } 480 }
519 // If the file went away and was replaced by a folder before we 481 // If the file went away and was replaced by a folder before we
520 // had a chance to process the event, resource might be a Folder. In 482 // had a chance to process the event, resource might be a Folder. In
521 // that case don't add it. 483 // that case don't add it.
522 if (resource is File) { 484 if (resource is File) {
523 File file = resource; 485 File file = resource;
524 if (_shouldFileBeAnalyzed(file)) { 486 if (_shouldFileBeAnalyzed(file)) {
525 ChangeSet changeSet = new ChangeSet(); 487 ChangeSet changeSet = new ChangeSet();
526 Source source = file.createSource(); 488 Source source = createSourceInContext(info.context, file);
527 changeSet.addedSource(source); 489 changeSet.addedSource(source);
528 applyChangesToContext(folder, changeSet); 490 applyChangesToContext(folder, changeSet);
529 info.sources[path] = source; 491 info.sources[path] = source;
530 } 492 }
531 } 493 }
532 break; 494 break;
533 case ChangeType.REMOVE: 495 case ChangeType.REMOVE:
534 // pubspec was removed, merge the context into its parent 496 // pubspec was removed, merge the context into its parent
535 if (info.isPubspec(path) && !info.isRoot) { 497 if (info.isPubspec(path) && !info.isRoot) {
536 _mergeContext(info); 498 _mergeContext(info);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 void _recomputePackageUriResolver(_ContextInfo info) { 583 void _recomputePackageUriResolver(_ContextInfo info) {
622 // TODO(paulberry): when computePackageMap is changed into an 584 // TODO(paulberry): when computePackageMap is changed into an
623 // asynchronous API call, we'll want to suspend analysis for this context 585 // asynchronous API call, we'll want to suspend analysis for this context
624 // while we're rerunning "pub list", since any analysis we complete while 586 // while we're rerunning "pub list", since any analysis we complete while
625 // "pub list" is in progress is just going to get thrown away anyhow. 587 // "pub list" is in progress is just going to get thrown away anyhow.
626 UriResolver packageUriResolver = 588 UriResolver packageUriResolver =
627 _computePackageUriResolver(info.folder, info); 589 _computePackageUriResolver(info.folder, info);
628 updateContextPackageUriResolver(info.folder, packageUriResolver); 590 updateContextPackageUriResolver(info.folder, packageUriResolver);
629 } 591 }
630 592
593 /**
594 * Create and return a source representing the given [file] within the given
595 * [context].
596 */
597 static Source createSourceInContext(AnalysisContext context, File file) {
598 // TODO(brianwilkerson) Optimize this, by allowing support for source
599 // factories to restore URI's from a file path rather than a source.
600 Source source = file.createSource();
601 if (context == null) {
602 return source;
603 }
604 Uri uri = context.sourceFactory.restoreUri(source);
605 return file.createSource(uri);
606 }
607
631 static bool _shouldFileBeAnalyzed(File file) { 608 static bool _shouldFileBeAnalyzed(File file) {
632 if (!(AnalysisEngine.isDartFileName(file.path) || 609 if (!(AnalysisEngine.isDartFileName(file.path) ||
633 AnalysisEngine.isHtmlFileName(file.path))) { 610 AnalysisEngine.isHtmlFileName(file.path))) {
634 return false; 611 return false;
635 } 612 }
636 // Emacs creates dummy links to track the fact that a file is open for 613 // Emacs creates dummy links to track the fact that a file is open for
637 // editing and has unsaved changes (e.g. having unsaved changes to 614 // editing and has unsaved changes (e.g. having unsaved changes to
638 // 'foo.dart' causes a link '.#foo.dart' to be created, which points to the 615 // 'foo.dart' causes a link '.#foo.dart' to be created, which points to the
639 // non-existent file 'username@hostname.pid'. To avoid these dummy links 616 // non-existent file 'username@hostname.pid'. To avoid these dummy links
640 // causing the analyzer to thrash, just ignore links to non-existent files. 617 // causing the analyzer to thrash, just ignore links to non-existent files.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 return excludes(resource.path); 699 return excludes(resource.path);
723 } 700 }
724 701
725 /** 702 /**
726 * Returns `true` if [path] is the pubspec file of this context. 703 * Returns `true` if [path] is the pubspec file of this context.
727 */ 704 */
728 bool isPubspec(String path) { 705 bool isPubspec(String path) {
729 return path == pubspecPath; 706 return path == pubspecPath;
730 } 707 }
731 } 708 }
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