OLD | NEW |
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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 compiler.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.reportError( | 398 compiler.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. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 compiler.withCurrentElement(library, () { |
485 compiler.reportWarning(library, | 485 compiler.reportWarningMessage( |
| 486 library, |
486 MessageKind.DUPLICATED_LIBRARY_RESOURCE, | 487 MessageKind.DUPLICATED_LIBRARY_RESOURCE, |
487 {'libraryName': library.libraryName, | 488 {'libraryName': library.libraryName, |
488 'resourceUri': resourceUri, | 489 'resourceUri': resourceUri, |
489 'canonicalUri1': library.canonicalUri, | 490 'canonicalUri1': library.canonicalUri, |
490 'canonicalUri2': existing.canonicalUri}); | 491 'canonicalUri2': existing.canonicalUri}); |
491 }); | 492 }); |
492 } else { | 493 } else { |
493 compiler.reportHint(library, | 494 compiler.reportHintMessage( |
| 495 library, |
494 MessageKind.DUPLICATED_RESOURCE, | 496 MessageKind.DUPLICATED_RESOURCE, |
495 {'resourceUri': resourceUri, | 497 {'resourceUri': resourceUri, |
496 'canonicalUri1': library.canonicalUri, | 498 'canonicalUri1': library.canonicalUri, |
497 'canonicalUri2': existing.canonicalUri}); | 499 'canonicalUri2': existing.canonicalUri}); |
498 } | 500 } |
499 } else if (library.hasLibraryName) { | 501 } else if (library.hasLibraryName) { |
500 String name = library.libraryOrScriptName; | 502 String name = library.libraryOrScriptName; |
501 existing = libraryNames.putIfAbsent(name, () => library); | 503 existing = libraryNames.putIfAbsent(name, () => library); |
502 if (!identical(existing, library)) { | 504 if (!identical(existing, library)) { |
503 compiler.withCurrentElement(library, () { | 505 compiler.withCurrentElement(library, () { |
504 compiler.reportWarning(library, | 506 compiler.reportWarningMessage( |
| 507 library, |
505 MessageKind.DUPLICATED_LIBRARY_NAME, | 508 MessageKind.DUPLICATED_LIBRARY_NAME, |
506 {'libraryName': name}); | 509 {'libraryName': name}); |
507 }); | 510 }); |
508 compiler.withCurrentElement(existing, () { | 511 compiler.withCurrentElement(existing, () { |
509 compiler.reportWarning(existing, | 512 compiler.reportWarningMessage( |
| 513 existing, |
510 MessageKind.DUPLICATED_LIBRARY_NAME, | 514 MessageKind.DUPLICATED_LIBRARY_NAME, |
511 {'libraryName': name}); | 515 {'libraryName': name}); |
512 }); | 516 }); |
513 } | 517 } |
514 } | 518 } |
515 } | 519 } |
516 | 520 |
517 /** | 521 /** |
518 * 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 |
519 * used as is, any URI resolution should be done beforehand. | 523 * used as is, any URI resolution should be done beforehand. |
520 */ | 524 */ |
521 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { | 525 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { |
522 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); | 526 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); |
523 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part); | 527 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part); |
524 if (readableUri == null) return new Future.value(); | 528 if (readableUri == null) return new Future.value(); |
525 return compiler.withCurrentElement(library, () { | 529 return compiler.withCurrentElement(library, () { |
526 return compiler.readScript(part, readableUri). | 530 return compiler.readScript(part, readableUri). |
527 then((Script sourceScript) { | 531 then((Script sourceScript) { |
528 if (sourceScript == null) return; | 532 if (sourceScript == null) return; |
529 | 533 |
530 CompilationUnitElementX unit = | 534 CompilationUnitElementX unit = |
531 new CompilationUnitElementX(sourceScript, library); | 535 new CompilationUnitElementX(sourceScript, library); |
532 compiler.withCurrentElement(unit, () { | 536 compiler.withCurrentElement(unit, () { |
533 compiler.scanner.scan(unit); | 537 compiler.scanner.scan(unit); |
534 if (unit.partTag == null && !sourceScript.isSynthesized) { | 538 if (unit.partTag == null && !sourceScript.isSynthesized) { |
535 compiler.reportError(unit, MessageKind.MISSING_PART_OF_TAG); | 539 compiler.reportErrorMessage( |
| 540 unit, MessageKind.MISSING_PART_OF_TAG); |
536 } | 541 } |
537 }); | 542 }); |
538 }); | 543 }); |
539 }); | 544 }); |
540 } | 545 } |
541 | 546 |
542 /** | 547 /** |
543 * Handle an import/export tag by loading the referenced library and | 548 * Handle an import/export tag by loading the referenced library and |
544 * registering its dependency in [handler] for the computation of the import/ | 549 * registering its dependency in [handler] for the computation of the import/ |
545 * 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 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 } else if (tag.isExport) { | 697 } else if (tag.isExport) { |
693 kind = MessageKind.EXPORT_BEFORE_PARTS; | 698 kind = MessageKind.EXPORT_BEFORE_PARTS; |
694 } else { | 699 } else { |
695 listener.internalError(tag, "Expected import or export."); | 700 listener.internalError(tag, "Expected import or export."); |
696 } | 701 } |
697 break; | 702 break; |
698 | 703 |
699 default: | 704 default: |
700 listener.internalError(tag, "Unexpected order of library tags."); | 705 listener.internalError(tag, "Unexpected order of library tags."); |
701 } | 706 } |
702 listener.reportError(tag, kind); | 707 listener.reportErrorMessage(tag, kind); |
703 } | 708 } |
704 tagState = NEXT[value]; | 709 tagState = NEXT[value]; |
705 if (value == LIBRARY) { | 710 if (value == LIBRARY) { |
706 hasLibraryDeclaration = true; | 711 hasLibraryDeclaration = true; |
707 } | 712 } |
708 } | 713 } |
709 } | 714 } |
710 | 715 |
711 /** | 716 /** |
712 * An [import] tag and the [importedLibrary] imported through [import]. | 717 * An [import] tag and the [importedLibrary] imported through [import]. |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 return pendingExports; | 929 return pendingExports; |
925 } | 930 } |
926 | 931 |
927 /** | 932 /** |
928 * Adds [element] to the export scope for this node. If the [element] name | 933 * Adds [element] to the export scope for this node. If the [element] name |
929 * is a duplicate, an error element is inserted into the export scope. | 934 * is a duplicate, an error element is inserted into the export scope. |
930 */ | 935 */ |
931 Element addElementToExportScope(Compiler compiler, Element element, | 936 Element addElementToExportScope(Compiler compiler, Element element, |
932 Link<ExportElement> exports) { | 937 Link<ExportElement> exports) { |
933 String name = element.name; | 938 String name = element.name; |
| 939 DiagnosticMessage error; |
| 940 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
934 | 941 |
935 void reportDuplicateExport(Element duplicate, | 942 void createDuplicateExportMessage( |
936 Link<ExportElement> duplicateExports, | 943 Element duplicate, |
937 {bool reportError: true}) { | 944 Link<ExportElement> duplicateExports) { |
938 assert(invariant(library, !duplicateExports.isEmpty, | 945 assert(invariant(library, !duplicateExports.isEmpty, |
939 message: "No export for $duplicate from ${duplicate.library} " | 946 message: "No export for $duplicate from ${duplicate.library} " |
940 "in $library.")); | 947 "in $library.")); |
941 compiler.withCurrentElement(library, () { | 948 compiler.withCurrentElement(library, () { |
942 for (ExportElement export in duplicateExports) { | 949 for (ExportElement export in duplicateExports) { |
943 if (reportError) { | 950 if (error == null) { |
944 compiler.reportError(export, | 951 error = compiler.createMessage( |
945 MessageKind.DUPLICATE_EXPORT, {'name': name}); | 952 export, |
946 reportError = false; | 953 MessageKind.DUPLICATE_EXPORT, |
| 954 {'name': name}); |
947 } else { | 955 } else { |
948 compiler.reportInfo(export, | 956 infos.add(compiler.createMessage( |
949 MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}); | 957 export, |
| 958 MessageKind.DUPLICATE_EXPORT_CONT, |
| 959 {'name': name})); |
950 } | 960 } |
951 } | 961 } |
952 }); | 962 }); |
953 } | 963 } |
954 | 964 |
955 void reportDuplicateExportDecl(Element duplicate, | 965 void createDuplicateExportDeclMessage( |
956 Link<ExportElement> duplicateExports) { | 966 Element duplicate, |
| 967 Link<ExportElement> duplicateExports) { |
957 assert(invariant(library, !duplicateExports.isEmpty, | 968 assert(invariant(library, !duplicateExports.isEmpty, |
958 message: "No export for $duplicate from ${duplicate.library} " | 969 message: "No export for $duplicate from ${duplicate.library} " |
959 "in $library.")); | 970 "in $library.")); |
960 compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL, | 971 infos.add(compiler.createMessage( |
961 {'name': name, 'uriString': duplicateExports.head.uri}); | 972 duplicate, |
| 973 MessageKind.DUPLICATE_EXPORT_DECL, |
| 974 {'name': name, 'uriString': duplicateExports.head.uri})); |
962 } | 975 } |
963 | 976 |
964 Element existingElement = exportScope[name]; | 977 Element existingElement = exportScope[name]; |
965 if (existingElement != null && existingElement != element) { | 978 if (existingElement != null && existingElement != element) { |
966 if (existingElement.isErroneous) { | 979 if (existingElement.isErroneous) { |
967 reportDuplicateExport(element, exports); | 980 createDuplicateExportMessage(element, exports); |
968 reportDuplicateExportDecl(element, exports); | 981 createDuplicateExportDeclMessage(element, exports); |
969 element = existingElement; | 982 element = existingElement; |
970 } else if (existingElement.library == library) { | 983 } else if (existingElement.library == library) { |
971 // Do nothing. [existingElement] hides [element]. | 984 // Do nothing. [existingElement] hides [element]. |
972 } else if (element.library == library) { | 985 } else if (element.library == library) { |
973 // [element] hides [existingElement]. | 986 // [element] hides [existingElement]. |
974 exportScope[name] = element; | 987 exportScope[name] = element; |
975 exporters[element] = exports; | 988 exporters[element] = exports; |
976 } else { | 989 } else { |
977 // Declared elements hide exported elements. | 990 // Declared elements hide exported elements. |
978 Link<ExportElement> existingExports = exporters[existingElement]; | 991 Link<ExportElement> existingExports = exporters[existingElement]; |
979 reportDuplicateExport(existingElement, existingExports); | 992 createDuplicateExportMessage(existingElement, existingExports); |
980 reportDuplicateExport(element, exports, reportError: false); | 993 createDuplicateExportMessage(element, exports); |
981 reportDuplicateExportDecl(existingElement, existingExports); | 994 createDuplicateExportDeclMessage(existingElement, existingExports); |
982 reportDuplicateExportDecl(element, exports); | 995 createDuplicateExportDeclMessage(element, exports); |
983 element = exportScope[name] = new ErroneousElementX( | 996 element = exportScope[name] = new ErroneousElementX( |
984 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library); | 997 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library); |
985 } | 998 } |
986 } else { | 999 } else { |
987 exportScope[name] = element; | 1000 exportScope[name] = element; |
988 exporters[element] = exports; | 1001 exporters[element] = exports; |
989 } | 1002 } |
| 1003 if (error != null) { |
| 1004 compiler.reportError(error, infos); |
| 1005 } |
990 return element; | 1006 return element; |
991 } | 1007 } |
992 | 1008 |
993 /** | 1009 /** |
994 * Propagates the exported [element] to all library nodes that depend upon | 1010 * Propagates the exported [element] to all library nodes that depend upon |
995 * this node. If the propagation updated any pending exports, [:true:] is | 1011 * this node. If the propagation updated any pending exports, [:true:] is |
996 * returned. | 1012 * returned. |
997 */ | 1013 */ |
998 bool propagateElement(Element element) { | 1014 bool propagateElement(Element element) { |
999 bool change = false; | 1015 bool change = false; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 /// export scope of [library]. | 1058 /// export scope of [library]. |
1043 void checkLibraryDependency(DiagnosticListener listener, | 1059 void checkLibraryDependency(DiagnosticListener listener, |
1044 LibraryDependency tag, | 1060 LibraryDependency tag, |
1045 LibraryElement library) { | 1061 LibraryElement library) { |
1046 if (tag == null || tag.combinators == null) return; | 1062 if (tag == null || tag.combinators == null) return; |
1047 for (Combinator combinator in tag.combinators) { | 1063 for (Combinator combinator in tag.combinators) { |
1048 for (Identifier identifier in combinator.identifiers) { | 1064 for (Identifier identifier in combinator.identifiers) { |
1049 String name = identifier.source; | 1065 String name = identifier.source; |
1050 Element element = library.findExported(name); | 1066 Element element = library.findExported(name); |
1051 if (element == null) { | 1067 if (element == null) { |
1052 listener.reportHint( | 1068 listener.reportHintMessage( |
1053 identifier, | 1069 identifier, |
1054 combinator.isHide | 1070 combinator.isHide |
1055 ? MessageKind.EMPTY_HIDE : MessageKind.EMPTY_SHOW, | 1071 ? MessageKind.EMPTY_HIDE : MessageKind.EMPTY_SHOW, |
1056 {'uri': library.canonicalUri, | 1072 {'uri': library.canonicalUri, |
1057 'name': name}); | 1073 'name': name}); |
1058 } | 1074 } |
1059 } | 1075 } |
1060 } | 1076 } |
1061 } | 1077 } |
1062 | 1078 |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 } | 1326 } |
1311 suffixes.add(const Link<Uri>().prepend(canonicalUri)); | 1327 suffixes.add(const Link<Uri>().prepend(canonicalUri)); |
1312 } | 1328 } |
1313 suffixChainMap[library] = suffixes; | 1329 suffixChainMap[library] = suffixes; |
1314 return; | 1330 return; |
1315 } | 1331 } |
1316 | 1332 |
1317 computeSuffixes(rootLibrary, const Link<Uri>()); | 1333 computeSuffixes(rootLibrary, const Link<Uri>()); |
1318 } | 1334 } |
1319 } | 1335 } |
OLD | NEW |