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

Side by Side Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 1017743003: Task: Create Export Namespace. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/dart_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698