| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 analyzer.src.task.dart; | 5 library analyzer.src.task.dart; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/generated/ast.dart'; | 9 import 'package:analyzer/src/generated/ast.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/src/generated/element.dart'; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 * The list will be empty if there were no errors, but will not be `null`. | 42 * The list will be empty if there were no errors, but will not be `null`. |
| 43 * | 43 * |
| 44 * The result is only available for targets representing a Dart library. | 44 * The result is only available for targets representing a Dart library. |
| 45 */ | 45 */ |
| 46 final ResultDescriptor<List<AnalysisError>> BUILD_LIBRARY_ERRORS = | 46 final ResultDescriptor<List<AnalysisError>> BUILD_LIBRARY_ERRORS = |
| 47 new ResultDescriptor<List<AnalysisError>>( | 47 new ResultDescriptor<List<AnalysisError>>( |
| 48 'BUILD_LIBRARY_ERRORS', AnalysisError.NO_ERRORS, | 48 'BUILD_LIBRARY_ERRORS', AnalysisError.NO_ERRORS, |
| 49 contributesTo: DART_ERRORS); | 49 contributesTo: DART_ERRORS); |
| 50 | 50 |
| 51 /** | 51 /** |
| 52 * The export [Namespace] of a library. |
| 53 * |
| 54 * The result is only available for targets representing a Dart library. |
| 55 */ |
| 56 final ResultDescriptor<Namespace> EXPORT_NAMESPACE = |
| 57 new ResultDescriptor<Namespace>('EXPORT_NAMESPACE', null); |
| 58 |
| 59 /** |
| 52 * The sources representing the export closure of a library. | 60 * The sources representing the export closure of a library. |
| 53 * | 61 * |
| 54 * The result is only available for targets representing a Dart library. | 62 * The result is only available for targets representing a Dart library. |
| 55 */ | 63 */ |
| 56 final ResultDescriptor<List<Source>> EXPORT_SOURCE_CLOSURE = | 64 final ResultDescriptor<List<Source>> EXPORT_SOURCE_CLOSURE = |
| 57 new ResultDescriptor<List<Source>>('EXPORT_SOURCE_CLOSURE', null); | 65 new ResultDescriptor<List<Source>>('EXPORT_SOURCE_CLOSURE', null); |
| 58 | 66 |
| 59 /** | 67 /** |
| 60 * The partial [LibraryElement] associated with a library. | 68 * The partial [LibraryElement] associated with a library. |
| 61 * | 69 * |
| (...skipping 10 matching lines...) Expand all Loading... |
| 72 * | 80 * |
| 73 * In addition to [LIBRARY_ELEMENT1] `imports` and `exports` of the | 81 * In addition to [LIBRARY_ELEMENT1] `imports` and `exports` of the |
| 74 * [LibraryElement] are set. | 82 * [LibraryElement] are set. |
| 75 * | 83 * |
| 76 * The result is only available for targets representing a Dart library. | 84 * The result is only available for targets representing a Dart library. |
| 77 */ | 85 */ |
| 78 final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT2 = | 86 final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT2 = |
| 79 new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT2', null); | 87 new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT2', null); |
| 80 | 88 |
| 81 /** | 89 /** |
| 90 * The partial [LibraryElement] associated with a library. |
| 91 * |
| 92 * In addition to [LIBRARY_ELEMENT2] `entryPoint` is set, if the library does |
| 93 * not declare one already and one of the exported libraries exports one. |
| 94 * |
| 95 * The result is only available for targets representing a Dart library. |
| 96 */ |
| 97 final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT3 = |
| 98 new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT3', null); |
| 99 |
| 100 /** |
| 82 * The partially resolved [CompilationUnit] associated with a unit. | 101 * The partially resolved [CompilationUnit] associated with a unit. |
| 83 * | 102 * |
| 84 * All declarations bound to the element defined by the declaration. | 103 * All declarations bound to the element defined by the declaration. |
| 85 * | 104 * |
| 86 * The result is only available for targets representing a unit. | 105 * The result is only available for targets representing a unit. |
| 87 */ | 106 */ |
| 88 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT1 = | 107 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT1 = |
| 89 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT1', null); | 108 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT1', null); |
| 90 | 109 |
| 91 /** | 110 /** |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 ImportElementImpl importElement = new ImportElementImpl(-1); | 381 ImportElementImpl importElement = new ImportElementImpl(-1); |
| 363 importElement.importedLibrary = importLibraryMap[coreLibrarySource]; | 382 importElement.importedLibrary = importLibraryMap[coreLibrarySource]; |
| 364 importElement.synthetic = true; | 383 importElement.synthetic = true; |
| 365 imports.add(importElement); | 384 imports.add(importElement); |
| 366 } | 385 } |
| 367 // | 386 // |
| 368 // Populate the library element. | 387 // Populate the library element. |
| 369 // | 388 // |
| 370 libraryElement.imports = imports; | 389 libraryElement.imports = imports; |
| 371 libraryElement.exports = exports; | 390 libraryElement.exports = exports; |
| 372 // TODO(scheglov) move after EXPORT_NAMESPACE or just this task | |
| 373 // if (libraryElement.entryPoint == null) { | |
| 374 // Namespace namespace = new NamespaceBuilder() | |
| 375 // .createExportNamespaceForLibrary(libraryElement); | |
| 376 // Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME); | |
| 377 // if (element is FunctionElement) { | |
| 378 // libraryElement.entryPoint = element; | |
| 379 // } | |
| 380 // } | |
| 381 // | 391 // |
| 382 // Record outputs. | 392 // Record outputs. |
| 383 // | 393 // |
| 384 outputs[LIBRARY_ELEMENT2] = libraryElement; | 394 outputs[LIBRARY_ELEMENT2] = libraryElement; |
| 385 outputs[RESOLVED_UNIT3] = libraryUnit; | 395 outputs[RESOLVED_UNIT3] = libraryUnit; |
| 386 outputs[BUILD_DIRECTIVES_ERRORS] = errors; | 396 outputs[BUILD_DIRECTIVES_ERRORS] = errors; |
| 387 } | 397 } |
| 388 | 398 |
| 389 /** | 399 /** |
| 390 * Return a map from the names of the inputs of this kind of task to the task | 400 * Return a map from the names of the inputs of this kind of task to the task |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 * Create a [BuildEnumMemberElementsTask] based on the given [target] in | 524 * Create a [BuildEnumMemberElementsTask] based on the given [target] in |
| 515 * the given [context]. | 525 * the given [context]. |
| 516 */ | 526 */ |
| 517 static BuildEnumMemberElementsTask createTask( | 527 static BuildEnumMemberElementsTask createTask( |
| 518 AnalysisContext context, AnalysisTarget target) { | 528 AnalysisContext context, AnalysisTarget target) { |
| 519 return new BuildEnumMemberElementsTask(context, target); | 529 return new BuildEnumMemberElementsTask(context, target); |
| 520 } | 530 } |
| 521 } | 531 } |
| 522 | 532 |
| 523 /** | 533 /** |
| 534 * A task that builds [EXPORT_NAMESPACE] and [LIBRARY_ELEMENT3] for a library. |
| 535 */ |
| 536 class BuildExportNamespaceTask extends SourceBasedAnalysisTask { |
| 537 /** |
| 538 * The name of the input for [LIBRARY_ELEMENT2] of a library. |
| 539 */ |
| 540 static const String LIBRARY2_ELEMENT_INPUT = 'LIBRARY2_ELEMENT_INPUT'; |
| 541 |
| 542 /** |
| 543 * The a [Source] to [PUBLIC_NAMESPACE] map input. |
| 544 */ |
| 545 static const String PUBLIC_NAMESPACES_INPUT = 'PUBLIC_NAMESPACES_INPUT'; |
| 546 |
| 547 /** |
| 548 * The task descriptor describing this kind of task. |
| 549 */ |
| 550 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( |
| 551 'BuildExportNamespaceTask', createTask, buildInputs, <ResultDescriptor>[ |
| 552 EXPORT_NAMESPACE, |
| 553 LIBRARY_ELEMENT3 |
| 554 ]); |
| 555 |
| 556 BuildExportNamespaceTask( |
| 557 InternalAnalysisContext context, AnalysisTarget target) |
| 558 : super(context, target); |
| 559 |
| 560 @override |
| 561 TaskDescriptor get descriptor => DESCRIPTOR; |
| 562 |
| 563 @override |
| 564 void internalPerform() { |
| 565 LibraryElementImpl library = getRequiredInput(LIBRARY2_ELEMENT_INPUT); |
| 566 Map<Source, Namespace> publicNamespaces = |
| 567 getRequiredInput(PUBLIC_NAMESPACES_INPUT); |
| 568 // |
| 569 // Compute export namespace. |
| 570 // |
| 571 ExportNamespaceBuilder builder = |
| 572 new ExportNamespaceBuilder(publicNamespaces); |
| 573 Namespace namespace = builder.build(library); |
| 574 // |
| 575 // Update entry point. |
| 576 // |
| 577 if (library.entryPoint == null) { |
| 578 Iterable<Element> exportedElements = namespace.definedNames.values; |
| 579 library.entryPoint = exportedElements.firstWhere( |
| 580 (element) => element is FunctionElement && element.isEntryPoint, |
| 581 orElse: () => null); |
| 582 } |
| 583 // |
| 584 // Record outputs. |
| 585 // |
| 586 outputs[EXPORT_NAMESPACE] = namespace; |
| 587 outputs[LIBRARY_ELEMENT3] = library; |
| 588 } |
| 589 |
| 590 /** |
| 591 * Return a map from the names of the inputs of this kind of task to the task |
| 592 * input descriptors describing those inputs for a task with the |
| 593 * given library [source]. |
| 594 */ |
| 595 static Map<String, TaskInput> buildInputs(Source source) { |
| 596 return <String, TaskInput>{ |
| 597 LIBRARY2_ELEMENT_INPUT: LIBRARY_ELEMENT2.inputFor(source), |
| 598 PUBLIC_NAMESPACES_INPUT: new ListToMapTaskInput<Source, Namespace>( |
| 599 EXPORT_SOURCE_CLOSURE.inputFor(source), |
| 600 (Source source) => PUBLIC_NAMESPACE.inputFor(source)) |
| 601 }; |
| 602 } |
| 603 |
| 604 /** |
| 605 * Create a [BuildExportNamespaceTask] based on the given [target] in |
| 606 * the given [context]. |
| 607 */ |
| 608 static BuildExportNamespaceTask createTask( |
| 609 AnalysisContext context, AnalysisTarget target) { |
| 610 return new BuildExportNamespaceTask(context, target); |
| 611 } |
| 612 } |
| 613 |
| 614 /** |
| 524 * A task that builds [EXPORT_SOURCE_CLOSURE] of a library. | 615 * A task that builds [EXPORT_SOURCE_CLOSURE] of a library. |
| 525 */ | 616 */ |
| 526 class BuildExportSourceClosureTask extends SourceBasedAnalysisTask { | 617 class BuildExportSourceClosureTask extends SourceBasedAnalysisTask { |
| 527 /** | 618 /** |
| 528 * The name of the input for [LIBRARY_ELEMENT2] of a library. | 619 * The name of the input for [LIBRARY_ELEMENT2] of a library. |
| 529 */ | 620 */ |
| 530 static const String LIBRARY2_ELEMENT_INPUT = 'LIBRARY2_ELEMENT_INPUT'; | 621 static const String LIBRARY2_ELEMENT_INPUT = 'LIBRARY2_ELEMENT_INPUT'; |
| 531 | 622 |
| 532 /** | 623 /** |
| 533 * The task descriptor describing this kind of task. | 624 * The task descriptor describing this kind of task. |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 /** | 1059 /** |
| 969 * Create a [BuildTypeProviderTask] based on the given [context]. | 1060 * Create a [BuildTypeProviderTask] based on the given [context]. |
| 970 */ | 1061 */ |
| 971 static BuildTypeProviderTask createTask( | 1062 static BuildTypeProviderTask createTask( |
| 972 AnalysisContext context, AnalysisContextTarget target) { | 1063 AnalysisContext context, AnalysisContextTarget target) { |
| 973 return new BuildTypeProviderTask(context, target); | 1064 return new BuildTypeProviderTask(context, target); |
| 974 } | 1065 } |
| 975 } | 1066 } |
| 976 | 1067 |
| 977 /** | 1068 /** |
| 1069 * The helper for building the export [Namespace] of a [LibraryElement]. |
| 1070 */ |
| 1071 class ExportNamespaceBuilder { |
| 1072 final Map<Source, Namespace> _publicNamespaces; |
| 1073 |
| 1074 ExportNamespaceBuilder(this._publicNamespaces); |
| 1075 |
| 1076 /** |
| 1077 * Build the export [Namespace] of the given [LibraryElement]. |
| 1078 */ |
| 1079 Namespace build(LibraryElement library) { |
| 1080 return new Namespace( |
| 1081 _createExportMapping(library, new HashSet<LibraryElement>())); |
| 1082 } |
| 1083 |
| 1084 /** |
| 1085 * Create a mapping table representing the export namespace of the given |
| 1086 * [library]. |
| 1087 * |
| 1088 * The given [visitedElements] a set of libraries that do not need to be |
| 1089 * visited when processing the export directives of the given library because |
| 1090 * all of the names defined by them will be added by another library. |
| 1091 */ |
| 1092 HashMap<String, Element> _createExportMapping( |
| 1093 LibraryElement library, HashSet<LibraryElement> visitedElements) { |
| 1094 visitedElements.add(library); |
| 1095 try { |
| 1096 HashMap<String, Element> definedNames = new HashMap<String, Element>(); |
| 1097 // Add names of the export directives. |
| 1098 for (ExportElement element in library.exports) { |
| 1099 LibraryElement exportedLibrary = element.exportedLibrary; |
| 1100 if (exportedLibrary != null && |
| 1101 !visitedElements.contains(exportedLibrary)) { |
| 1102 // |
| 1103 // The exported library will be null if the URI does not reference a |
| 1104 // valid library. |
| 1105 // |
| 1106 HashMap<String, Element> exportedNames = |
| 1107 _createExportMapping(exportedLibrary, visitedElements); |
| 1108 exportedNames = _applyCombinators(exportedNames, element.combinators); |
| 1109 definedNames.addAll(exportedNames); |
| 1110 } |
| 1111 } |
| 1112 // Add names of the public namespace. |
| 1113 { |
| 1114 Namespace publicNamespace = _publicNamespaces[library.source]; |
| 1115 if (publicNamespace != null) { |
| 1116 definedNames.addAll(publicNamespace.definedNames); |
| 1117 } |
| 1118 } |
| 1119 return definedNames; |
| 1120 } finally { |
| 1121 visitedElements.remove(library); |
| 1122 } |
| 1123 } |
| 1124 |
| 1125 /** |
| 1126 * Apply the given [combinators] to all of the names in [definedNames]. |
| 1127 */ |
| 1128 static HashMap<String, Element> _applyCombinators( |
| 1129 HashMap<String, Element> definedNames, |
| 1130 List<NamespaceCombinator> combinators) { |
| 1131 for (NamespaceCombinator combinator in combinators) { |
| 1132 if (combinator is HideElementCombinator) { |
| 1133 _hide(definedNames, combinator.hiddenNames); |
| 1134 } else if (combinator is ShowElementCombinator) { |
| 1135 definedNames = _show(definedNames, combinator.shownNames); |
| 1136 } |
| 1137 } |
| 1138 return definedNames; |
| 1139 } |
| 1140 |
| 1141 /** |
| 1142 * Hide all of the [hiddenNames] by removing them from the given |
| 1143 * [definedNames]. |
| 1144 */ |
| 1145 static void _hide( |
| 1146 HashMap<String, Element> definedNames, List<String> hiddenNames) { |
| 1147 for (String name in hiddenNames) { |
| 1148 definedNames.remove(name); |
| 1149 definedNames.remove('$name='); |
| 1150 } |
| 1151 } |
| 1152 |
| 1153 /** |
| 1154 * Show only the given [shownNames] by removing all other names from the given |
| 1155 * [definedNames]. |
| 1156 */ |
| 1157 static HashMap<String, Element> _show( |
| 1158 HashMap<String, Element> definedNames, List<String> shownNames) { |
| 1159 HashMap<String, Element> newNames = new HashMap<String, Element>(); |
| 1160 for (String name in shownNames) { |
| 1161 Element element = definedNames[name]; |
| 1162 if (element != null) { |
| 1163 newNames[name] = element; |
| 1164 } |
| 1165 String setterName = '$name='; |
| 1166 element = definedNames[setterName]; |
| 1167 if (element != null) { |
| 1168 newNames[setterName] = element; |
| 1169 } |
| 1170 } |
| 1171 return newNames; |
| 1172 } |
| 1173 } |
| 1174 |
| 1175 /** |
| 978 * A pair of a library [Source] and a unit [Source] in this library. | 1176 * A pair of a library [Source] and a unit [Source] in this library. |
| 979 */ | 1177 */ |
| 980 class LibraryUnitTarget implements AnalysisTarget { | 1178 class LibraryUnitTarget implements AnalysisTarget { |
| 981 final Source library; | 1179 final Source library; |
| 982 final Source unit; | 1180 final Source unit; |
| 983 LibraryUnitTarget(this.library, this.unit); | 1181 LibraryUnitTarget(this.library, this.unit); |
| 984 | 1182 |
| 985 @override | 1183 @override |
| 986 int get hashCode { | 1184 int get hashCode { |
| 987 return JenkinsSmiHash.combine(library.hashCode, unit.hashCode); | 1185 return JenkinsSmiHash.combine(library.hashCode, unit.hashCode); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1066 if (directive is ExportDirective) { | 1264 if (directive is ExportDirective) { |
| 1067 exportedSources.add(referencedSource); | 1265 exportedSources.add(referencedSource); |
| 1068 } else if (directive is ImportDirective) { | 1266 } else if (directive is ImportDirective) { |
| 1069 importedSources.add(referencedSource); | 1267 importedSources.add(referencedSource); |
| 1070 } else if (directive is PartDirective) { | 1268 } else if (directive is PartDirective) { |
| 1071 if (referencedSource != source) { | 1269 if (referencedSource != source) { |
| 1072 includedSources.add(referencedSource); | 1270 includedSources.add(referencedSource); |
| 1073 } | 1271 } |
| 1074 } else { | 1272 } else { |
| 1075 throw new AnalysisException( | 1273 throw new AnalysisException( |
| 1076 "$runtimeType failed to handle a ${directive.runtimeType}"); | 1274 '$runtimeType failed to handle a ${directive.runtimeType}'); |
| 1077 } | 1275 } |
| 1078 } | 1276 } |
| 1079 } | 1277 } |
| 1080 } | 1278 } |
| 1081 } | 1279 } |
| 1082 // | 1280 // |
| 1083 // Always include "dart:core" source. | 1281 // Always include "dart:core" source. |
| 1084 // | 1282 // |
| 1085 Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE); | 1283 Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE); |
| 1086 importedSources.add(coreLibrarySource); | 1284 importedSources.add(coreLibrarySource); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 } | 1455 } |
| 1258 | 1456 |
| 1259 /** | 1457 /** |
| 1260 * Create a [ScanDartTask] based on the given [target] in the given [context]. | 1458 * Create a [ScanDartTask] based on the given [target] in the given [context]. |
| 1261 */ | 1459 */ |
| 1262 static ScanDartTask createTask( | 1460 static ScanDartTask createTask( |
| 1263 AnalysisContext context, AnalysisTarget target) { | 1461 AnalysisContext context, AnalysisTarget target) { |
| 1264 return new ScanDartTask(context, target); | 1462 return new ScanDartTask(context, target); |
| 1265 } | 1463 } |
| 1266 } | 1464 } |
| OLD | NEW |