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

Side by Side Diff: pkg/compiler/lib/src/library_loader.dart

Issue 1383483006: Extract DiagnosticReporter implementation from Compiler. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Fixes after rebase. Created 5 years, 2 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 dart2js.library_loader; 5 library dart2js.library_loader;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'common/names.dart' show 9 import 'common/names.dart' show
10 Uris; 10 Uris;
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 } 351 }
352 352
353 Future<LibraryElement> loadLibrary(Uri resolvedUri) { 353 Future<LibraryElement> loadLibrary(Uri resolvedUri) {
354 return measure(() { 354 return measure(() {
355 assert(currentHandler == null); 355 assert(currentHandler == null);
356 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the 356 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the
357 // loading of a library cluster. 357 // loading of a library cluster.
358 currentHandler = new LibraryDependencyHandler(this); 358 currentHandler = new LibraryDependencyHandler(this);
359 return createLibrary(currentHandler, null, resolvedUri) 359 return createLibrary(currentHandler, null, resolvedUri)
360 .then((LibraryElement library) { 360 .then((LibraryElement library) {
361 return compiler.withCurrentElement(library, () { 361 return reporter.withCurrentElement(library, () {
362 return measure(() { 362 return measure(() {
363 currentHandler.computeExports(); 363 currentHandler.computeExports();
364 LoadedLibraries loadedLibraries = 364 LoadedLibraries loadedLibraries =
365 new _LoadedLibraries(library, currentHandler.nodeMap, this); 365 new _LoadedLibraries(library, currentHandler.nodeMap, this);
366 currentHandler = null; 366 currentHandler = null;
367 return compiler.onLibrariesLoaded(loadedLibraries) 367 return compiler.onLibrariesLoaded(loadedLibraries)
368 .then((_) => library); 368 .then((_) => library);
369 }); 369 });
370 }); 370 });
371 }); 371 });
372 }); 372 });
373 } 373 }
374 374
375 /** 375 /**
376 * Processes the library tags in [library]. 376 * Processes the library tags in [library].
377 * 377 *
378 * The imported/exported libraries are loaded and processed recursively but 378 * The imported/exported libraries are loaded and processed recursively but
379 * the import/export scopes are not set up. 379 * the import/export scopes are not set up.
380 */ 380 */
381 Future processLibraryTags(LibraryDependencyHandler handler, 381 Future processLibraryTags(LibraryDependencyHandler handler,
382 LibraryElementX library) { 382 LibraryElementX library) {
383 TagState tagState = new TagState(); 383 TagState tagState = new TagState();
384 384
385 bool importsDartCore = false; 385 bool importsDartCore = false;
386 LinkBuilder<LibraryDependencyElementX> libraryDependencies = 386 LinkBuilder<LibraryDependencyElementX> libraryDependencies =
387 new LinkBuilder<LibraryDependencyElementX>(); 387 new LinkBuilder<LibraryDependencyElementX>();
388 Uri base = library.entryCompilationUnit.script.readableUri; 388 Uri base = library.entryCompilationUnit.script.readableUri;
389 389
390 return Future.forEach(library.tags, (LibraryTag tag) { 390 return Future.forEach(library.tags, (LibraryTag tag) {
391 return compiler.withCurrentElement(library, () { 391 return reporter.withCurrentElement(library, () {
392 392
393 Uri computeUri(LibraryDependency node) { 393 Uri computeUri(LibraryDependency node) {
394 String tagUriString = node.uri.dartString.slowToString(); 394 String tagUriString = node.uri.dartString.slowToString();
395 try { 395 try {
396 return Uri.parse(tagUriString); 396 return Uri.parse(tagUriString);
397 } on FormatException { 397 } on FormatException {
398 compiler.reportErrorMessage( 398 reporter.reportErrorMessage(
399 node.uri, 399 node.uri,
400 MessageKind.INVALID_URI, {'uri': tagUriString}); 400 MessageKind.INVALID_URI, {'uri': tagUriString});
401 return null; 401 return null;
402 } 402 }
403 } 403 }
404 404
405 if (tag.isImport) { 405 if (tag.isImport) {
406 Uri uri = computeUri(tag); 406 Uri uri = computeUri(tag);
407 if (uri == null) { 407 if (uri == null) {
408 // Skip this erroneous import. 408 // Skip this erroneous import.
409 return new Future.value(); 409 return new Future.value();
410 } 410 }
411 // TODO(johnniwinther): Create imports during parsing. 411 // TODO(johnniwinther): Create imports during parsing.
412 ImportElementX import = 412 ImportElementX import =
413 new ImportElementX(library.entryCompilationUnit, tag, uri); 413 new ImportElementX(library.entryCompilationUnit, tag, uri);
414 tagState.checkTag(TagState.IMPORT_OR_EXPORT, import.node, compiler); 414 tagState.checkTag(TagState.IMPORT_OR_EXPORT, import.node, reporter);
415 if (import.uri == Uris.dart_core) { 415 if (import.uri == Uris.dart_core) {
416 importsDartCore = true; 416 importsDartCore = true;
417 } 417 }
418 library.addImportDeclaration(import); 418 library.addImportDeclaration(import);
419 libraryDependencies.addLast(import); 419 libraryDependencies.addLast(import);
420 } else if (tag.isExport) { 420 } else if (tag.isExport) {
421 Uri uri = computeUri(tag); 421 Uri uri = computeUri(tag);
422 if (uri == null) { 422 if (uri == null) {
423 // Skip this erroneous export. 423 // Skip this erroneous export.
424 return new Future.value(); 424 return new Future.value();
425 } 425 }
426 // TODO(johnniwinther): Create exports during parsing. 426 // TODO(johnniwinther): Create exports during parsing.
427 ExportElementX export = 427 ExportElementX export =
428 new ExportElementX(library.entryCompilationUnit, tag, uri); 428 new ExportElementX(library.entryCompilationUnit, tag, uri);
429 tagState.checkTag(TagState.IMPORT_OR_EXPORT, export.node, compiler); 429 tagState.checkTag(TagState.IMPORT_OR_EXPORT, export.node, reporter);
430 library.addExportDeclaration(export); 430 library.addExportDeclaration(export);
431 libraryDependencies.addLast(export); 431 libraryDependencies.addLast(export);
432 } else if (tag.isLibraryName) { 432 } else if (tag.isLibraryName) {
433 tagState.checkTag(TagState.LIBRARY, tag, compiler); 433 tagState.checkTag(TagState.LIBRARY, tag, reporter);
434 if (library.libraryTag == null) { 434 if (library.libraryTag == null) {
435 // Use the first if there are multiple (which is reported as an 435 // Use the first if there are multiple (which is reported as an
436 // error in [TagState.checkTag]). 436 // error in [TagState.checkTag]).
437 library.libraryTag = tag; 437 library.libraryTag = tag;
438 } 438 }
439 } else if (tag.isPart) { 439 } else if (tag.isPart) {
440 Part part = tag; 440 Part part = tag;
441 StringNode uri = part.uri; 441 StringNode uri = part.uri;
442 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); 442 Uri resolvedUri = base.resolve(uri.dartString.slowToString());
443 tagState.checkTag(TagState.PART, part, compiler); 443 tagState.checkTag(TagState.PART, part, reporter);
444 return scanPart(part, resolvedUri, library); 444 return scanPart(part, resolvedUri, library);
445 } else { 445 } else {
446 compiler.internalError(tag, "Unhandled library tag."); 446 reporter.internalError(tag, "Unhandled library tag.");
447 } 447 }
448 }); 448 });
449 }).then((_) { 449 }).then((_) {
450 return compiler.onLibraryScanned(library, handler); 450 return compiler.onLibraryScanned(library, handler);
451 }).then((_) { 451 }).then((_) {
452 return compiler.withCurrentElement(library, () { 452 return reporter.withCurrentElement(library, () {
453 checkDuplicatedLibraryName(library); 453 checkDuplicatedLibraryName(library);
454 454
455 // Import dart:core if not already imported. 455 // Import dart:core if not already imported.
456 if (!importsDartCore && library.canonicalUri != Uris.dart_core) { 456 if (!importsDartCore && library.canonicalUri != Uris.dart_core) {
457 return createLibrary(handler, null, Uris.dart_core) 457 return createLibrary(handler, null, Uris.dart_core)
458 .then((LibraryElement coreLibrary) { 458 .then((LibraryElement coreLibrary) {
459 handler.registerDependency(library, 459 handler.registerDependency(library,
460 new SyntheticImportElement( 460 new SyntheticImportElement(
461 library.entryCompilationUnit, Uris.dart_core), 461 library.entryCompilationUnit, Uris.dart_core),
462 coreLibrary); 462 coreLibrary);
463 }); 463 });
464 } 464 }
465 }); 465 });
466 }).then((_) { 466 }).then((_) {
467 return Future.forEach(libraryDependencies.toList(), 467 return Future.forEach(libraryDependencies.toList(),
468 (LibraryDependencyElementX libraryDependency) { 468 (LibraryDependencyElementX libraryDependency) {
469 return compiler.withCurrentElement(library, () { 469 return reporter.withCurrentElement(library, () {
470 return registerLibraryFromImportExport( 470 return registerLibraryFromImportExport(
471 handler, library, libraryDependency); 471 handler, library, libraryDependency);
472 }); 472 });
473 }); 473 });
474 }); 474 });
475 } 475 }
476 476
477 void checkDuplicatedLibraryName(LibraryElement library) { 477 void checkDuplicatedLibraryName(LibraryElement library) {
478 if (library.isInternalLibrary) return; 478 if (library.isInternalLibrary) return;
479 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; 479 Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
480 LibraryElement existing = 480 LibraryElement existing =
481 libraryResourceUriMap.putIfAbsent(resourceUri, () => library); 481 libraryResourceUriMap.putIfAbsent(resourceUri, () => library);
482 if (!identical(existing, library)) { 482 if (!identical(existing, library)) {
483 if (library.hasLibraryName) { 483 if (library.hasLibraryName) {
484 compiler.withCurrentElement(library, () { 484 reporter.withCurrentElement(library, () {
485 compiler.reportWarningMessage( 485 reporter.reportWarningMessage(
486 library, 486 library,
487 MessageKind.DUPLICATED_LIBRARY_RESOURCE, 487 MessageKind.DUPLICATED_LIBRARY_RESOURCE,
488 {'libraryName': library.libraryName, 488 {'libraryName': library.libraryName,
489 'resourceUri': resourceUri, 489 'resourceUri': resourceUri,
490 'canonicalUri1': library.canonicalUri, 490 'canonicalUri1': library.canonicalUri,
491 'canonicalUri2': existing.canonicalUri}); 491 'canonicalUri2': existing.canonicalUri});
492 }); 492 });
493 } else { 493 } else {
494 compiler.reportHintMessage( 494 reporter.reportHintMessage(
495 library, 495 library,
496 MessageKind.DUPLICATED_RESOURCE, 496 MessageKind.DUPLICATED_RESOURCE,
497 {'resourceUri': resourceUri, 497 {'resourceUri': resourceUri,
498 'canonicalUri1': library.canonicalUri, 498 'canonicalUri1': library.canonicalUri,
499 'canonicalUri2': existing.canonicalUri}); 499 'canonicalUri2': existing.canonicalUri});
500 } 500 }
501 } else if (library.hasLibraryName) { 501 } else if (library.hasLibraryName) {
502 String name = library.libraryOrScriptName; 502 String name = library.libraryOrScriptName;
503 existing = libraryNames.putIfAbsent(name, () => library); 503 existing = libraryNames.putIfAbsent(name, () => library);
504 if (!identical(existing, library)) { 504 if (!identical(existing, library)) {
505 compiler.withCurrentElement(library, () { 505 reporter.withCurrentElement(library, () {
506 compiler.reportWarningMessage( 506 reporter.reportWarningMessage(
507 library, 507 library,
508 MessageKind.DUPLICATED_LIBRARY_NAME, 508 MessageKind.DUPLICATED_LIBRARY_NAME,
509 {'libraryName': name}); 509 {'libraryName': name});
510 }); 510 });
511 compiler.withCurrentElement(existing, () { 511 reporter.withCurrentElement(existing, () {
512 compiler.reportWarningMessage( 512 reporter.reportWarningMessage(
513 existing, 513 existing,
514 MessageKind.DUPLICATED_LIBRARY_NAME, 514 MessageKind.DUPLICATED_LIBRARY_NAME,
515 {'libraryName': name}); 515 {'libraryName': name});
516 }); 516 });
517 } 517 }
518 } 518 }
519 } 519 }
520 520
521 /** 521 /**
522 * Handle a part tag in the scope of [library]. The [resolvedUri] given is 522 * Handle a part tag in the scope of [library]. The [resolvedUri] given is
523 * used as is, any URI resolution should be done beforehand. 523 * used as is, any URI resolution should be done beforehand.
524 */ 524 */
525 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { 525 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) {
526 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); 526 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri);
527 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part); 527 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part);
528 if (readableUri == null) return new Future.value(); 528 if (readableUri == null) return new Future.value();
529 return compiler.withCurrentElement(library, () { 529 return reporter.withCurrentElement(library, () {
530 return compiler.readScript(part, readableUri). 530 return compiler.readScript(part, readableUri).
531 then((Script sourceScript) { 531 then((Script sourceScript) {
532 if (sourceScript == null) return; 532 if (sourceScript == null) return;
533 533
534 CompilationUnitElementX unit = 534 CompilationUnitElementX unit =
535 new CompilationUnitElementX(sourceScript, library); 535 new CompilationUnitElementX(sourceScript, library);
536 compiler.withCurrentElement(unit, () { 536 reporter.withCurrentElement(unit, () {
537 compiler.scanner.scan(unit); 537 compiler.scanner.scan(unit);
538 if (unit.partTag == null && !sourceScript.isSynthesized) { 538 if (unit.partTag == null && !sourceScript.isSynthesized) {
539 compiler.reportErrorMessage( 539 reporter.reportErrorMessage(
540 unit, MessageKind.MISSING_PART_OF_TAG); 540 unit, MessageKind.MISSING_PART_OF_TAG);
541 } 541 }
542 }); 542 });
543 }); 543 });
544 }); 544 });
545 } 545 }
546 546
547 /** 547 /**
548 * Handle an import/export tag by loading the referenced library and 548 * Handle an import/export tag by loading the referenced library and
549 * registering its dependency in [handler] for the computation of the import/ 549 * registering its dependency in [handler] for the computation of the import/
550 * export scope. If the tag does not contain a valid URI, then its dependency 550 * export scope. If the tag does not contain a valid URI, then its dependency
551 * is not registered in [handler]. 551 * is not registered in [handler].
552 */ 552 */
553 Future<Null> registerLibraryFromImportExport( 553 Future<Null> registerLibraryFromImportExport(
554 LibraryDependencyHandler handler, 554 LibraryDependencyHandler handler,
555 LibraryElement library, 555 LibraryElement library,
556 LibraryDependencyElementX libraryDependency) { 556 LibraryDependencyElementX libraryDependency) {
557 Uri base = library.canonicalUri; 557 Uri base = library.canonicalUri;
558 Uri resolvedUri = base.resolveUri(libraryDependency.uri); 558 Uri resolvedUri = base.resolveUri(libraryDependency.uri);
559 return createLibrary(handler, library, resolvedUri, libraryDependency) 559 return createLibrary(handler, library, resolvedUri, libraryDependency)
560 .then((LibraryElement loadedLibrary) { 560 .then((LibraryElement loadedLibrary) {
561 if (loadedLibrary == null) return; 561 if (loadedLibrary == null) return;
562 compiler.withCurrentElement(library, () { 562 reporter.withCurrentElement(library, () {
563 libraryDependency.libraryDependency = loadedLibrary; 563 libraryDependency.libraryDependency = loadedLibrary;
564 handler.registerDependency( 564 handler.registerDependency(
565 library, libraryDependency, loadedLibrary); 565 library, libraryDependency, loadedLibrary);
566 }); 566 });
567 }); 567 });
568 } 568 }
569 569
570 /// Loads the deserialized [library] with the [handler]. 570 /// Loads the deserialized [library] with the [handler].
571 /// 571 ///
572 /// All libraries imported or exported transitively from [library] will be 572 /// All libraries imported or exported transitively from [library] will be
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 } 605 }
606 library = compiler.serialization.readLibrary(resolvedUri); 606 library = compiler.serialization.readLibrary(resolvedUri);
607 if (library != null) { 607 if (library != null) {
608 return loadDeserializedLibrary(handler, library); 608 return loadDeserializedLibrary(handler, library);
609 } 609 }
610 var readScript = compiler.readScript; 610 var readScript = compiler.readScript;
611 if (readableUri == null) { 611 if (readableUri == null) {
612 readableUri = resolvedUri; 612 readableUri = resolvedUri;
613 readScript = compiler.synthesizeScript; 613 readScript = compiler.synthesizeScript;
614 } 614 }
615 return compiler.withCurrentElement(importingLibrary, () { 615 return reporter.withCurrentElement(importingLibrary, () {
616 return readScript(node, readableUri).then((Script script) { 616 return readScript(node, readableUri).then((Script script) {
617 if (script == null) return null; 617 if (script == null) return null;
618 LibraryElement element = 618 LibraryElement element =
619 createLibrarySync(handler, script, resolvedUri); 619 createLibrarySync(handler, script, resolvedUri);
620 return processLibraryTags(handler, element).then((_) { 620 return processLibraryTags(handler, element).then((_) {
621 compiler.withCurrentElement(element, () { 621 reporter.withCurrentElement(element, () {
622 handler.registerLibraryExports(element); 622 handler.registerLibraryExports(element);
623 }); 623 });
624 return element; 624 return element;
625 }); 625 });
626 }); 626 });
627 }); 627 });
628 } 628 }
629 629
630 LibraryElement createLibrarySync( 630 LibraryElement createLibrarySync(
631 LibraryDependencyHandler handler, 631 LibraryDependencyHandler handler,
632 Script script, 632 Script script,
633 Uri resolvedUri) { 633 Uri resolvedUri) {
634 LibraryElement element = new LibraryElementX(script, resolvedUri); 634 LibraryElement element = new LibraryElementX(script, resolvedUri);
635 return compiler.withCurrentElement(element, () { 635 return reporter.withCurrentElement(element, () {
636 if (handler != null) { 636 if (handler != null) {
637 handler.registerNewLibrary(element); 637 handler.registerNewLibrary(element);
638 libraryCanonicalUriMap[resolvedUri] = element; 638 libraryCanonicalUriMap[resolvedUri] = element;
639 } 639 }
640 native.maybeEnableNative(compiler, element); 640 native.maybeEnableNative(compiler, element);
641 compiler.scanner.scanLibrary(element); 641 compiler.scanner.scanLibrary(element);
642 return element; 642 return element;
643 }); 643 });
644 } 644 }
645 } 645 }
(...skipping 26 matching lines...) Expand all
672 IMPORT_OR_EXPORT, 672 IMPORT_OR_EXPORT,
673 PART, 673 PART,
674 ]; 674 ];
675 675
676 int tagState = TagState.NO_TAG_SEEN; 676 int tagState = TagState.NO_TAG_SEEN;
677 677
678 bool hasLibraryDeclaration = false; 678 bool hasLibraryDeclaration = false;
679 679
680 /// If [value] is less than [tagState] complain. Regardless, update 680 /// If [value] is less than [tagState] complain. Regardless, update
681 /// [tagState] using transition function for state machine. 681 /// [tagState] using transition function for state machine.
682 void checkTag(int value, LibraryTag tag, DiagnosticListener listener) { 682 void checkTag(int value, LibraryTag tag, DiagnosticReporter reporter) {
683 if (tagState > value) { 683 if (tagState > value) {
684 MessageKind kind; 684 MessageKind kind;
685 switch (value) { 685 switch (value) {
686 case LIBRARY: 686 case LIBRARY:
687 if (hasLibraryDeclaration) { 687 if (hasLibraryDeclaration) {
688 kind = MessageKind.ONLY_ONE_LIBRARY_TAG; 688 kind = MessageKind.ONLY_ONE_LIBRARY_TAG;
689 } else { 689 } else {
690 kind = MessageKind.LIBRARY_TAG_MUST_BE_FIRST; 690 kind = MessageKind.LIBRARY_TAG_MUST_BE_FIRST;
691 } 691 }
692 break; 692 break;
693 693
694 case IMPORT_OR_EXPORT: 694 case IMPORT_OR_EXPORT:
695 if (tag.isImport) { 695 if (tag.isImport) {
696 kind = MessageKind.IMPORT_BEFORE_PARTS; 696 kind = MessageKind.IMPORT_BEFORE_PARTS;
697 } else if (tag.isExport) { 697 } else if (tag.isExport) {
698 kind = MessageKind.EXPORT_BEFORE_PARTS; 698 kind = MessageKind.EXPORT_BEFORE_PARTS;
699 } else { 699 } else {
700 listener.internalError(tag, "Expected import or export."); 700 reporter.internalError(tag, "Expected import or export.");
701 } 701 }
702 break; 702 break;
703 703
704 default: 704 default:
705 listener.internalError(tag, "Unexpected order of library tags."); 705 reporter.internalError(tag, "Unexpected order of library tags.");
706 } 706 }
707 listener.reportErrorMessage(tag, kind); 707 reporter.reportErrorMessage(tag, kind);
708 } 708 }
709 tagState = NEXT[value]; 709 tagState = NEXT[value];
710 if (value == LIBRARY) { 710 if (value == LIBRARY) {
711 hasLibraryDeclaration = true; 711 hasLibraryDeclaration = true;
712 } 712 }
713 } 713 }
714 } 714 }
715 715
716 /** 716 /**
717 * An [import] tag and the [importedLibrary] imported through [import]. 717 * An [import] tag and the [importedLibrary] imported through [import].
718 */ 718 */
719 class ImportLink { 719 class ImportLink {
720 final ImportElementX import; 720 final ImportElementX import;
721 final LibraryElement importedLibrary; 721 final LibraryElement importedLibrary;
722 722
723 ImportLink(this.import, this.importedLibrary); 723 ImportLink(this.import, this.importedLibrary);
724 724
725 /** 725 /**
726 * Imports the library into the [importingLibrary]. 726 * Imports the library into the [importingLibrary].
727 */ 727 */
728 void importLibrary(Compiler compiler, LibraryElementX importingLibrary) { 728 void importLibrary(DiagnosticReporter reporter,
729 LibraryElementX importingLibrary) {
729 assert(invariant(importingLibrary, 730 assert(invariant(importingLibrary,
730 importedLibrary.exportsHandled, 731 importedLibrary.exportsHandled,
731 message: 'Exports not handled on $importedLibrary')); 732 message: 'Exports not handled on $importedLibrary'));
732 Import tag = import.node; 733 Import tag = import.node;
733 CombinatorFilter combinatorFilter = 734 CombinatorFilter combinatorFilter =
734 new CombinatorFilter.fromTag(tag); 735 new CombinatorFilter.fromTag(tag);
735 if (tag != null && tag.prefix != null) { 736 if (tag != null && tag.prefix != null) {
736 String prefix = tag.prefix.source; 737 String prefix = tag.prefix.source;
737 Element existingElement = importingLibrary.find(prefix); 738 Element existingElement = importingLibrary.find(prefix);
738 PrefixElementX prefixElement; 739 PrefixElementX prefixElement;
739 if (existingElement == null || !existingElement.isPrefix) { 740 if (existingElement == null || !existingElement.isPrefix) {
740 prefixElement = new PrefixElementX( 741 prefixElement = new PrefixElementX(
741 prefix, 742 prefix,
742 importingLibrary.entryCompilationUnit, 743 importingLibrary.entryCompilationUnit,
743 tag.getBeginToken(), 744 tag.getBeginToken(),
744 tag.isDeferred ? import : null); 745 tag.isDeferred ? import : null);
745 } else { 746 } else {
746 prefixElement = existingElement; 747 prefixElement = existingElement;
747 } 748 }
748 importingLibrary.addToScope(prefixElement, compiler); 749 importingLibrary.addToScope(prefixElement, reporter);
749 importedLibrary.forEachExport((Element element) { 750 importedLibrary.forEachExport((Element element) {
750 if (combinatorFilter.exclude(element)) return; 751 if (combinatorFilter.exclude(element)) return;
751 prefixElement.addImport(element, import, compiler); 752 prefixElement.addImport(element, import, reporter);
752 }); 753 });
753 import.prefix = prefixElement; 754 import.prefix = prefixElement;
754 if (prefixElement.isDeferred) { 755 if (prefixElement.isDeferred) {
755 prefixElement.addImport( 756 prefixElement.addImport(
756 new DeferredLoaderGetterElementX(prefixElement), 757 new DeferredLoaderGetterElementX(prefixElement),
757 import, compiler); 758 import, reporter);
758 } 759 }
759 } else { 760 } else {
760 importedLibrary.forEachExport((Element element) { 761 importedLibrary.forEachExport((Element element) {
761 compiler.withCurrentElement(importingLibrary, () { 762 reporter.withCurrentElement(importingLibrary, () {
762 if (combinatorFilter.exclude(element)) return; 763 if (combinatorFilter.exclude(element)) return;
763 importingLibrary.addImport(element, import, compiler); 764 importingLibrary.addImport(element, import, reporter);
764 }); 765 });
765 }); 766 });
766 } 767 }
767 } 768 }
768 } 769 }
769 770
770 /** 771 /**
771 * The combinator filter computed from an export tag and the library dependency 772 * The combinator filter computed from an export tag and the library dependency
772 * node for the library that declared the export tag. This represents an edge in 773 * node for the library that declared the export tag. This represents an edge in
773 * the library dependency graph. 774 * the library dependency graph.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 pendingExportMap[element] = const Link<ExportElement>(); 879 pendingExportMap[element] = const Link<ExportElement>();
879 } 880 }
880 } 881 }
881 882
882 /// Register the already computed export scope of [exportedLibraryElement] to 883 /// Register the already computed export scope of [exportedLibraryElement] to
883 /// export from the library of this node through the [export] declaration 884 /// export from the library of this node through the [export] declaration
884 /// with the given combination [filter]. 885 /// with the given combination [filter].
885 /// 886 ///
886 /// Additionally, check that all names in the show/hide combinators are in the 887 /// Additionally, check that all names in the show/hide combinators are in the
887 /// export scope of [exportedLibraryElement]. 888 /// export scope of [exportedLibraryElement].
888 void registerHandledExports(DiagnosticListener listener, 889 void registerHandledExports(DiagnosticReporter reporter,
889 LibraryElement exportedLibraryElement, 890 LibraryElement exportedLibraryElement,
890 ExportElementX export, 891 ExportElementX export,
891 CombinatorFilter filter) { 892 CombinatorFilter filter) {
892 assert(invariant(library, exportedLibraryElement.exportsHandled)); 893 assert(invariant(library, exportedLibraryElement.exportsHandled));
893 exportedLibraryElement.forEachExport((Element exportedElement) { 894 exportedLibraryElement.forEachExport((Element exportedElement) {
894 if (!filter.exclude(exportedElement)) { 895 if (!filter.exclude(exportedElement)) {
895 Link<ExportElement> exports = 896 Link<ExportElement> exports =
896 pendingExportMap.putIfAbsent(exportedElement, 897 pendingExportMap.putIfAbsent(exportedElement,
897 () => const Link<ExportElement>()); 898 () => const Link<ExportElement>());
898 pendingExportMap[exportedElement] = exports.prepend(export); 899 pendingExportMap[exportedElement] = exports.prepend(export);
899 } 900 }
900 }); 901 });
901 listener.withCurrentElement(library, () { 902 reporter.withCurrentElement(library, () {
902 checkLibraryDependency(listener, export.node, exportedLibraryElement); 903 checkLibraryDependency(reporter, export.node, exportedLibraryElement);
903 }); 904 });
904 } 905 }
905 906
906 /** 907 /**
907 * Registers the compute export scope with the node library. 908 * Registers the compute export scope with the node library.
908 */ 909 */
909 void registerExports() { 910 void registerExports() {
910 library.setExports(exportScope.values.toList()); 911 library.setExports(exportScope.values.toList());
911 } 912 }
912 913
913 /** 914 /**
914 * Registers the imports of the node library. 915 * Registers the imports of the node library.
915 */ 916 */
916 void registerImports(Compiler compiler) { 917 void registerImports(DiagnosticReporter reporter) {
917 for (ImportLink link in imports) { 918 for (ImportLink link in imports) {
918 link.importLibrary(compiler, library); 919 link.importLibrary(reporter, library);
919 } 920 }
920 } 921 }
921 922
922 /** 923 /**
923 * Copies and clears pending export set for this node. 924 * Copies and clears pending export set for this node.
924 */ 925 */
925 Map<Element, Link<ExportElement>> pullPendingExports() { 926 Map<Element, Link<ExportElement>> pullPendingExports() {
926 Map<Element, Link<ExportElement>> pendingExports = 927 Map<Element, Link<ExportElement>> pendingExports =
927 new Map<Element, Link<ExportElement>>.from(pendingExportMap); 928 new Map<Element, Link<ExportElement>>.from(pendingExportMap);
928 pendingExportMap.clear(); 929 pendingExportMap.clear();
929 return pendingExports; 930 return pendingExports;
930 } 931 }
931 932
932 /** 933 /**
933 * Adds [element] to the export scope for this node. If the [element] name 934 * Adds [element] to the export scope for this node. If the [element] name
934 * is a duplicate, an error element is inserted into the export scope. 935 * is a duplicate, an error element is inserted into the export scope.
935 */ 936 */
936 Element addElementToExportScope(Compiler compiler, Element element, 937 Element addElementToExportScope(
937 Link<ExportElement> exports) { 938 DiagnosticReporter reporter,
939 Element element,
940 Link<ExportElement> exports) {
938 String name = element.name; 941 String name = element.name;
939 DiagnosticMessage error; 942 DiagnosticMessage error;
940 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; 943 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
941 944
942 void createDuplicateExportMessage( 945 void createDuplicateExportMessage(
943 Element duplicate, 946 Element duplicate,
944 Link<ExportElement> duplicateExports) { 947 Link<ExportElement> duplicateExports) {
945 assert(invariant(library, !duplicateExports.isEmpty, 948 assert(invariant(library, !duplicateExports.isEmpty,
946 message: "No export for $duplicate from ${duplicate.library} " 949 message: "No export for $duplicate from ${duplicate.library} "
947 "in $library.")); 950 "in $library."));
948 compiler.withCurrentElement(library, () { 951 reporter.withCurrentElement(library, () {
949 for (ExportElement export in duplicateExports) { 952 for (ExportElement export in duplicateExports) {
950 if (error == null) { 953 if (error == null) {
951 error = compiler.createMessage( 954 error = reporter.createMessage(
952 export, 955 export,
953 MessageKind.DUPLICATE_EXPORT, 956 MessageKind.DUPLICATE_EXPORT,
954 {'name': name}); 957 {'name': name});
955 } else { 958 } else {
956 infos.add(compiler.createMessage( 959 infos.add(reporter.createMessage(
957 export, 960 export,
958 MessageKind.DUPLICATE_EXPORT_CONT, 961 MessageKind.DUPLICATE_EXPORT_CONT,
959 {'name': name})); 962 {'name': name}));
960 } 963 }
961 } 964 }
962 }); 965 });
963 } 966 }
964 967
965 void createDuplicateExportDeclMessage( 968 void createDuplicateExportDeclMessage(
966 Element duplicate, 969 Element duplicate,
967 Link<ExportElement> duplicateExports) { 970 Link<ExportElement> duplicateExports) {
968 assert(invariant(library, !duplicateExports.isEmpty, 971 assert(invariant(library, !duplicateExports.isEmpty,
969 message: "No export for $duplicate from ${duplicate.library} " 972 message: "No export for $duplicate from ${duplicate.library} "
970 "in $library.")); 973 "in $library."));
971 infos.add(compiler.createMessage( 974 infos.add(reporter.createMessage(
972 duplicate, 975 duplicate,
973 MessageKind.DUPLICATE_EXPORT_DECL, 976 MessageKind.DUPLICATE_EXPORT_DECL,
974 {'name': name, 'uriString': duplicateExports.head.uri})); 977 {'name': name, 'uriString': duplicateExports.head.uri}));
975 } 978 }
976 979
977 Element existingElement = exportScope[name]; 980 Element existingElement = exportScope[name];
978 if (existingElement != null && existingElement != element) { 981 if (existingElement != null && existingElement != element) {
979 if (existingElement.isErroneous) { 982 if (existingElement.isErroneous) {
980 createDuplicateExportMessage(element, exports); 983 createDuplicateExportMessage(element, exports);
981 createDuplicateExportDeclMessage(element, exports); 984 createDuplicateExportDeclMessage(element, exports);
(...skipping 12 matching lines...) Expand all
994 createDuplicateExportDeclMessage(existingElement, existingExports); 997 createDuplicateExportDeclMessage(existingElement, existingExports);
995 createDuplicateExportDeclMessage(element, exports); 998 createDuplicateExportDeclMessage(element, exports);
996 element = exportScope[name] = new ErroneousElementX( 999 element = exportScope[name] = new ErroneousElementX(
997 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library); 1000 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
998 } 1001 }
999 } else { 1002 } else {
1000 exportScope[name] = element; 1003 exportScope[name] = element;
1001 exporters[element] = exports; 1004 exporters[element] = exports;
1002 } 1005 }
1003 if (error != null) { 1006 if (error != null) {
1004 compiler.reportError(error, infos); 1007 reporter.reportError(error, infos);
1005 } 1008 }
1006 return element; 1009 return element;
1007 } 1010 }
1008 1011
1009 /** 1012 /**
1010 * Propagates the exported [element] to all library nodes that depend upon 1013 * Propagates the exported [element] to all library nodes that depend upon
1011 * this node. If the propagation updated any pending exports, [:true:] is 1014 * this node. If the propagation updated any pending exports, [:true:] is
1012 * returned. 1015 * returned.
1013 */ 1016 */
1014 bool propagateElement(Element element) { 1017 bool propagateElement(Element element) {
(...skipping 18 matching lines...) Expand all
1033 changed = true; 1036 changed = true;
1034 return const Link<ExportElement>(); 1037 return const Link<ExportElement>();
1035 }); 1038 });
1036 pendingExportMap[element] = exports.prepend(export); 1039 pendingExportMap[element] = exports.prepend(export);
1037 } 1040 }
1038 return changed; 1041 return changed;
1039 } 1042 }
1040 1043
1041 /// Check that all names in the show/hide combinators of imports and exports 1044 /// Check that all names in the show/hide combinators of imports and exports
1042 /// are in the export scope of the imported/exported libraries. 1045 /// are in the export scope of the imported/exported libraries.
1043 void checkCombinators(DiagnosticListener listener) { 1046 void checkCombinators(DiagnosticReporter reporter) {
1044 listener.withCurrentElement(library, () { 1047 reporter.withCurrentElement(library, () {
1045 for (ImportLink importLink in imports) { 1048 for (ImportLink importLink in imports) {
1046 checkLibraryDependency( 1049 checkLibraryDependency(
1047 listener, importLink.import.node, importLink.importedLibrary); 1050 reporter, importLink.import.node, importLink.importedLibrary);
1048 } 1051 }
1049 }); 1052 });
1050 for (ExportLink exportLink in dependencies) { 1053 for (ExportLink exportLink in dependencies) {
1051 listener.withCurrentElement(exportLink.exportNode.library, () { 1054 reporter.withCurrentElement(exportLink.exportNode.library, () {
1052 checkLibraryDependency(listener, exportLink.export.node, library); 1055 checkLibraryDependency(reporter, exportLink.export.node, library);
1053 }); 1056 });
1054 } 1057 }
1055 } 1058 }
1056 1059
1057 /// Check that all names in the show/hide combinators of [tag] are in the 1060 /// Check that all names in the show/hide combinators of [tag] are in the
1058 /// export scope of [library]. 1061 /// export scope of [library].
1059 void checkLibraryDependency(DiagnosticListener listener, 1062 void checkLibraryDependency(
1060 LibraryDependency tag, 1063 DiagnosticReporter reporter,
1061 LibraryElement library) { 1064 LibraryDependency tag,
1065 LibraryElement library) {
1062 if (tag == null || tag.combinators == null) return; 1066 if (tag == null || tag.combinators == null) return;
1063 for (Combinator combinator in tag.combinators) { 1067 for (Combinator combinator in tag.combinators) {
1064 for (Identifier identifier in combinator.identifiers) { 1068 for (Identifier identifier in combinator.identifiers) {
1065 String name = identifier.source; 1069 String name = identifier.source;
1066 Element element = library.findExported(name); 1070 Element element = library.findExported(name);
1067 if (element == null) { 1071 if (element == null) {
1068 listener.reportHintMessage( 1072 reporter.reportHintMessage(
1069 identifier, 1073 identifier,
1070 combinator.isHide 1074 combinator.isHide
1071 ? MessageKind.EMPTY_HIDE : MessageKind.EMPTY_SHOW, 1075 ? MessageKind.EMPTY_HIDE : MessageKind.EMPTY_SHOW,
1072 {'uri': library.canonicalUri, 1076 {'uri': library.canonicalUri,
1073 'name': name}); 1077 'name': name});
1074 } 1078 }
1075 } 1079 }
1076 } 1080 }
1077 } 1081 }
1078 1082
(...skipping 16 matching lines...) Expand all
1095 * part of the dependency graph of this handler since their export scopes have 1099 * part of the dependency graph of this handler since their export scopes have
1096 * already been computed. 1100 * already been computed.
1097 */ 1101 */
1098 Map<LibraryElement, LibraryDependencyNode> nodeMap = 1102 Map<LibraryElement, LibraryDependencyNode> nodeMap =
1099 new Map<LibraryElement, LibraryDependencyNode>(); 1103 new Map<LibraryElement, LibraryDependencyNode>();
1100 1104
1101 LibraryDependencyHandler(this.task); 1105 LibraryDependencyHandler(this.task);
1102 1106
1103 Compiler get compiler => task.compiler; 1107 Compiler get compiler => task.compiler;
1104 1108
1109 DiagnosticReporter get reporter => task.reporter;
1110
1105 /// The libraries loaded with this handler. 1111 /// The libraries loaded with this handler.
1106 Iterable<LibraryElement> get loadedLibraries => nodeMap.keys; 1112 Iterable<LibraryElement> get loadedLibraries => nodeMap.keys;
1107 1113
1108 /** 1114 /**
1109 * Performs a fixed-point computation on the export scopes of all registered 1115 * Performs a fixed-point computation on the export scopes of all registered
1110 * libraries and creates the import/export of the libraries based on the 1116 * libraries and creates the import/export of the libraries based on the
1111 * fixed-point. 1117 * fixed-point.
1112 */ 1118 */
1113 void computeExports() { 1119 void computeExports() {
1114 bool changed = true; 1120 bool changed = true;
1115 while (changed) { 1121 while (changed) {
1116 changed = false; 1122 changed = false;
1117 Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>> tasks = 1123 Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>> tasks =
1118 new Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>>(); 1124 new Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>>();
1119 1125
1120 // Locally defined elements take precedence over exported 1126 // Locally defined elements take precedence over exported
1121 // elements. So we must propagate local elements first. We 1127 // elements. So we must propagate local elements first. We
1122 // ensure this by pulling the pending exports before 1128 // ensure this by pulling the pending exports before
1123 // propagating. This enforces that we handle exports 1129 // propagating. This enforces that we handle exports
1124 // breadth-first, with locally defined elements being level 0. 1130 // breadth-first, with locally defined elements being level 0.
1125 nodeMap.forEach((_, LibraryDependencyNode node) { 1131 nodeMap.forEach((_, LibraryDependencyNode node) {
1126 Map<Element, Link<ExportElement>> pendingExports = 1132 Map<Element, Link<ExportElement>> pendingExports =
1127 node.pullPendingExports(); 1133 node.pullPendingExports();
1128 tasks[node] = pendingExports; 1134 tasks[node] = pendingExports;
1129 }); 1135 });
1130 tasks.forEach((LibraryDependencyNode node, 1136 tasks.forEach((LibraryDependencyNode node,
1131 Map<Element, Link<ExportElement>> pendingExports) { 1137 Map<Element, Link<ExportElement>> pendingExports) {
1132 pendingExports.forEach((Element element, Link<ExportElement> exports) { 1138 pendingExports.forEach((Element element, Link<ExportElement> exports) {
1133 element = node.addElementToExportScope(compiler, element, exports); 1139 element = node.addElementToExportScope(reporter, element, exports);
1134 if (node.propagateElement(element)) { 1140 if (node.propagateElement(element)) {
1135 changed = true; 1141 changed = true;
1136 } 1142 }
1137 }); 1143 });
1138 }); 1144 });
1139 } 1145 }
1140 1146
1141 // Setup export scopes. These have to be set before computing the import 1147 // Setup export scopes. These have to be set before computing the import
1142 // scopes to avoid accessing uncomputed export scopes during handling of 1148 // scopes to avoid accessing uncomputed export scopes during handling of
1143 // imports. 1149 // imports.
1144 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { 1150 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
1145 node.registerExports(); 1151 node.registerExports();
1146 }); 1152 });
1147 1153
1148 // Setup import scopes. 1154 // Setup import scopes.
1149 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { 1155 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
1150 node.registerImports(compiler); 1156 node.registerImports(reporter);
1151 }); 1157 });
1152 1158
1153 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { 1159 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
1154 node.checkCombinators(compiler); 1160 node.checkCombinators(reporter);
1155 }); 1161 });
1156 } 1162 }
1157 1163
1158 /// Registers that [library] depends on [loadedLibrary] through 1164 /// Registers that [library] depends on [loadedLibrary] through
1159 /// [libraryDependency]. 1165 /// [libraryDependency].
1160 void registerDependency(LibraryElementX library, 1166 void registerDependency(LibraryElementX library,
1161 LibraryDependencyElementX libraryDependency, 1167 LibraryDependencyElementX libraryDependency,
1162 LibraryElement loadedLibrary) { 1168 LibraryElement loadedLibrary) {
1163 if (libraryDependency.isExport) { 1169 if (libraryDependency.isExport) {
1164 // [loadedLibrary] is exported by [library]. 1170 // [loadedLibrary] is exported by [library].
1165 LibraryDependencyNode exportingNode = nodeMap[library]; 1171 LibraryDependencyNode exportingNode = nodeMap[library];
1166 if (loadedLibrary.exportsHandled) { 1172 if (loadedLibrary.exportsHandled) {
1167 // Export scope already computed on [loadedLibrary]. 1173 // Export scope already computed on [loadedLibrary].
1168 CombinatorFilter combinatorFilter = 1174 CombinatorFilter combinatorFilter =
1169 new CombinatorFilter.fromTag(libraryDependency.node); 1175 new CombinatorFilter.fromTag(libraryDependency.node);
1170 exportingNode.registerHandledExports( 1176 exportingNode.registerHandledExports(
1171 compiler, loadedLibrary, libraryDependency, combinatorFilter); 1177 reporter, loadedLibrary, libraryDependency, combinatorFilter);
1172 return; 1178 return;
1173 } 1179 }
1174 LibraryDependencyNode exportedNode = nodeMap[loadedLibrary]; 1180 LibraryDependencyNode exportedNode = nodeMap[loadedLibrary];
1175 assert(invariant(loadedLibrary, exportedNode != null, 1181 assert(invariant(loadedLibrary, exportedNode != null,
1176 message: "$loadedLibrary has not been registered")); 1182 message: "$loadedLibrary has not been registered"));
1177 assert(invariant(library, exportingNode != null, 1183 assert(invariant(library, exportingNode != null,
1178 message: "$library has not been registered")); 1184 message: "$library has not been registered"));
1179 exportedNode.registerExportDependency(libraryDependency, exportingNode); 1185 exportedNode.registerExportDependency(libraryDependency, exportingNode);
1180 } else if (libraryDependency == null || libraryDependency.isImport) { 1186 } else if (libraryDependency == null || libraryDependency.isImport) {
1181 // [loadedLibrary] is imported by [library]. 1187 // [loadedLibrary] is imported by [library].
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 } 1332 }
1327 suffixes.add(const Link<Uri>().prepend(canonicalUri)); 1333 suffixes.add(const Link<Uri>().prepend(canonicalUri));
1328 } 1334 }
1329 suffixChainMap[library] = suffixes; 1335 suffixChainMap[library] = suffixes;
1330 return; 1336 return;
1331 } 1337 }
1332 1338
1333 computeSuffixes(rootLibrary, const Link<Uri>()); 1339 computeSuffixes(rootLibrary, const Link<Uri>());
1334 } 1340 }
1335 } 1341 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698