| 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/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/visitor.dart'; | 10 import 'package:analyzer/dart/ast/visitor.dart'; |
| (...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 | 976 |
| 977 BuildDirectiveElementsTask( | 977 BuildDirectiveElementsTask( |
| 978 InternalAnalysisContext context, AnalysisTarget target) | 978 InternalAnalysisContext context, AnalysisTarget target) |
| 979 : super(context, target); | 979 : super(context, target); |
| 980 | 980 |
| 981 @override | 981 @override |
| 982 TaskDescriptor get descriptor => DESCRIPTOR; | 982 TaskDescriptor get descriptor => DESCRIPTOR; |
| 983 | 983 |
| 984 @override | 984 @override |
| 985 void internalPerform() { | 985 void internalPerform() { |
| 986 List<AnalysisError> errors = <AnalysisError>[]; | |
| 987 // | 986 // |
| 988 // Prepare inputs. | 987 // Prepare inputs. |
| 989 // | 988 // |
| 990 LibraryElementImpl libraryElement = getRequiredInput(LIBRARY_INPUT); | 989 LibraryElementImpl libraryElement = getRequiredInput(LIBRARY_INPUT); |
| 991 CompilationUnit libraryUnit = getRequiredInput(UNIT_INPUT_NAME); | 990 CompilationUnit libraryUnit = getRequiredInput(UNIT_INPUT_NAME); |
| 992 Map<Source, LibraryElement> importLibraryMap = | 991 Map<Source, LibraryElement> importLibraryMap = |
| 993 getRequiredInput(IMPORTS_LIBRARY_ELEMENT_INPUT_NAME); | 992 getRequiredInput(IMPORTS_LIBRARY_ELEMENT_INPUT_NAME); |
| 994 Map<Source, LibraryElement> exportLibraryMap = | 993 Map<Source, LibraryElement> exportLibraryMap = |
| 995 getRequiredInput(EXPORTS_LIBRARY_ELEMENT_INPUT_NAME); | 994 getRequiredInput(EXPORTS_LIBRARY_ELEMENT_INPUT_NAME); |
| 996 Map<Source, SourceKind> importSourceKindMap = | 995 Map<Source, SourceKind> importSourceKindMap = |
| 997 getRequiredInput(IMPORTS_SOURCE_KIND_INPUT_NAME); | 996 getRequiredInput(IMPORTS_SOURCE_KIND_INPUT_NAME); |
| 998 Map<Source, SourceKind> exportSourceKindMap = | 997 Map<Source, SourceKind> exportSourceKindMap = |
| 999 getRequiredInput(EXPORTS_SOURCE_KIND_INPUT_NAME); | 998 getRequiredInput(EXPORTS_SOURCE_KIND_INPUT_NAME); |
| 1000 Source librarySource = libraryElement.source; | |
| 1001 // | 999 // |
| 1002 // Resolve directives. | 1000 // Build elements. |
| 1003 // | 1001 // |
| 1004 HashMap<String, PrefixElementImpl> nameToPrefixMap = | 1002 DirectiveElementBuilder builder = new DirectiveElementBuilder( |
| 1005 new HashMap<String, PrefixElementImpl>(); | 1003 context, |
| 1006 List<ImportElement> imports = <ImportElement>[]; | 1004 libraryElement, |
| 1007 List<ExportElement> exports = <ExportElement>[]; | 1005 importLibraryMap, |
| 1008 bool explicitlyImportsCore = false; | 1006 importSourceKindMap, |
| 1009 for (Directive directive in libraryUnit.directives) { | 1007 exportLibraryMap, |
| 1010 if (directive is ImportDirective) { | 1008 exportSourceKindMap); |
| 1011 ImportDirective importDirective = directive; | 1009 libraryUnit.accept(builder); |
| 1012 String uriContent = importDirective.uriContent; | |
| 1013 if (DartUriResolver.isDartExtUri(uriContent)) { | |
| 1014 libraryElement.hasExtUri = true; | |
| 1015 } | |
| 1016 Source importedSource = importDirective.source; | |
| 1017 if (importedSource != null && context.exists(importedSource)) { | |
| 1018 // The imported source will be null if the URI in the import | |
| 1019 // directive was invalid. | |
| 1020 LibraryElement importedLibrary = importLibraryMap[importedSource]; | |
| 1021 if (importedLibrary != null) { | |
| 1022 if (importedLibrary.isDartCore) { | |
| 1023 explicitlyImportsCore = true; | |
| 1024 } | |
| 1025 ImportElementImpl importElement = | |
| 1026 new ImportElementImpl(directive.offset); | |
| 1027 StringLiteral uriLiteral = importDirective.uri; | |
| 1028 if (uriLiteral != null) { | |
| 1029 importElement.uriOffset = uriLiteral.offset; | |
| 1030 importElement.uriEnd = uriLiteral.end; | |
| 1031 } | |
| 1032 importElement.uri = uriContent; | |
| 1033 importElement.deferred = importDirective.deferredKeyword != null; | |
| 1034 importElement.combinators = _buildCombinators(importDirective); | |
| 1035 importElement.importedLibrary = importedLibrary; | |
| 1036 _setDoc(importElement, importDirective); | |
| 1037 SimpleIdentifier prefixNode = directive.prefix; | |
| 1038 if (prefixNode != null) { | |
| 1039 importElement.prefixOffset = prefixNode.offset; | |
| 1040 String prefixName = prefixNode.name; | |
| 1041 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; | |
| 1042 if (prefix == null) { | |
| 1043 prefix = new PrefixElementImpl.forNode(prefixNode); | |
| 1044 nameToPrefixMap[prefixName] = prefix; | |
| 1045 } | |
| 1046 importElement.prefix = prefix; | |
| 1047 prefixNode.staticElement = prefix; | |
| 1048 } | |
| 1049 directive.element = importElement; | |
| 1050 imports.add(importElement); | |
| 1051 if (importSourceKindMap[importedSource] != SourceKind.LIBRARY) { | |
| 1052 ErrorCode errorCode = (importElement.isDeferred | |
| 1053 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY | |
| 1054 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY); | |
| 1055 errors.add(new AnalysisError(importedSource, uriLiteral.offset, | |
| 1056 uriLiteral.length, errorCode, [uriLiteral.toSource()])); | |
| 1057 } | |
| 1058 } | |
| 1059 } | |
| 1060 } else if (directive is ExportDirective) { | |
| 1061 ExportDirective exportDirective = directive; | |
| 1062 Source exportedSource = exportDirective.source; | |
| 1063 if (exportedSource != null && context.exists(exportedSource)) { | |
| 1064 // The exported source will be null if the URI in the export | |
| 1065 // directive was invalid. | |
| 1066 LibraryElement exportedLibrary = exportLibraryMap[exportedSource]; | |
| 1067 if (exportedLibrary != null) { | |
| 1068 ExportElementImpl exportElement = | |
| 1069 new ExportElementImpl(directive.offset); | |
| 1070 StringLiteral uriLiteral = exportDirective.uri; | |
| 1071 if (uriLiteral != null) { | |
| 1072 exportElement.uriOffset = uriLiteral.offset; | |
| 1073 exportElement.uriEnd = uriLiteral.end; | |
| 1074 } | |
| 1075 exportElement.uri = exportDirective.uriContent; | |
| 1076 exportElement.combinators = _buildCombinators(exportDirective); | |
| 1077 exportElement.exportedLibrary = exportedLibrary; | |
| 1078 _setDoc(exportElement, exportDirective); | |
| 1079 directive.element = exportElement; | |
| 1080 exports.add(exportElement); | |
| 1081 if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) { | |
| 1082 errors.add(new AnalysisError( | |
| 1083 exportedSource, | |
| 1084 uriLiteral.offset, | |
| 1085 uriLiteral.length, | |
| 1086 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, | |
| 1087 [uriLiteral.toSource()])); | |
| 1088 } | |
| 1089 } | |
| 1090 } | |
| 1091 } | |
| 1092 } | |
| 1093 // | |
| 1094 // Ensure "dart:core" import. | |
| 1095 // | |
| 1096 Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE); | |
| 1097 if (!explicitlyImportsCore && coreLibrarySource != librarySource) { | |
| 1098 ImportElementImpl importElement = new ImportElementImpl(-1); | |
| 1099 importElement.importedLibrary = importLibraryMap[coreLibrarySource]; | |
| 1100 importElement.synthetic = true; | |
| 1101 imports.add(importElement); | |
| 1102 } | |
| 1103 // | |
| 1104 // Populate the library element. | |
| 1105 // | |
| 1106 libraryElement.imports = imports; | |
| 1107 libraryElement.exports = exports; | |
| 1108 // See commentary in the computation of the LIBRARY_CYCLE result | 1010 // See commentary in the computation of the LIBRARY_CYCLE result |
| 1109 // for details on library cycle invalidation. | 1011 // for details on library cycle invalidation. |
| 1110 libraryElement.invalidateLibraryCycles(); | 1012 libraryElement.invalidateLibraryCycles(); |
| 1111 // | 1013 // |
| 1112 // Record outputs. | 1014 // Record outputs. |
| 1113 // | 1015 // |
| 1114 outputs[LIBRARY_ELEMENT2] = libraryElement; | 1016 outputs[LIBRARY_ELEMENT2] = libraryElement; |
| 1115 outputs[BUILD_DIRECTIVES_ERRORS] = errors; | 1017 outputs[BUILD_DIRECTIVES_ERRORS] = builder.errors; |
| 1116 } | 1018 } |
| 1117 | 1019 |
| 1118 /** | 1020 /** |
| 1119 * If the given [node] has a documentation comment, remember its content | |
| 1120 * and range into the given [element]. | |
| 1121 */ | |
| 1122 void _setDoc(ElementImpl element, AnnotatedNode node) { | |
| 1123 Comment comment = node.documentationComment; | |
| 1124 if (comment != null && comment.isDocumentation) { | |
| 1125 element.documentationComment = | |
| 1126 comment.tokens.map((Token t) => t.lexeme).join('\n'); | |
| 1127 element.setDocRange(comment.offset, comment.length); | |
| 1128 } | |
| 1129 } | |
| 1130 | |
| 1131 /** | |
| 1132 * Return a map from the names of the inputs of this kind of task to the task | 1021 * Return a map from the names of the inputs of this kind of task to the task |
| 1133 * input descriptors describing those inputs for a task with the | 1022 * input descriptors describing those inputs for a task with the |
| 1134 * given library [libSource]. | 1023 * given library [libSource]. |
| 1135 */ | 1024 */ |
| 1136 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { | 1025 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
| 1137 Source source = target; | 1026 Source source = target; |
| 1138 return <String, TaskInput>{ | 1027 return <String, TaskInput>{ |
| 1139 LIBRARY_INPUT: LIBRARY_ELEMENT1.of(source), | 1028 LIBRARY_INPUT: LIBRARY_ELEMENT1.of(source), |
| 1140 UNIT_INPUT_NAME: | 1029 UNIT_INPUT_NAME: |
| 1141 RESOLVED_UNIT1.of(new LibrarySpecificUnit(source, source)), | 1030 RESOLVED_UNIT1.of(new LibrarySpecificUnit(source, source)), |
| 1142 IMPORTS_LIBRARY_ELEMENT_INPUT_NAME: | 1031 IMPORTS_LIBRARY_ELEMENT_INPUT_NAME: |
| 1143 IMPORTED_LIBRARIES.of(source).toMapOf(LIBRARY_ELEMENT1), | 1032 IMPORTED_LIBRARIES.of(source).toMapOf(LIBRARY_ELEMENT1), |
| 1144 EXPORTS_LIBRARY_ELEMENT_INPUT_NAME: | 1033 EXPORTS_LIBRARY_ELEMENT_INPUT_NAME: |
| 1145 EXPORTED_LIBRARIES.of(source).toMapOf(LIBRARY_ELEMENT1), | 1034 EXPORTED_LIBRARIES.of(source).toMapOf(LIBRARY_ELEMENT1), |
| 1146 IMPORTS_SOURCE_KIND_INPUT_NAME: | 1035 IMPORTS_SOURCE_KIND_INPUT_NAME: |
| 1147 IMPORTED_LIBRARIES.of(source).toMapOf(SOURCE_KIND), | 1036 IMPORTED_LIBRARIES.of(source).toMapOf(SOURCE_KIND), |
| 1148 EXPORTS_SOURCE_KIND_INPUT_NAME: | 1037 EXPORTS_SOURCE_KIND_INPUT_NAME: |
| 1149 EXPORTED_LIBRARIES.of(source).toMapOf(SOURCE_KIND) | 1038 EXPORTED_LIBRARIES.of(source).toMapOf(SOURCE_KIND) |
| 1150 }; | 1039 }; |
| 1151 } | 1040 } |
| 1152 | 1041 |
| 1153 /** | 1042 /** |
| 1154 * Create a [BuildDirectiveElementsTask] based on the given [target] in | 1043 * Create a [BuildDirectiveElementsTask] based on the given [target] in |
| 1155 * the given [context]. | 1044 * the given [context]. |
| 1156 */ | 1045 */ |
| 1157 static BuildDirectiveElementsTask createTask( | 1046 static BuildDirectiveElementsTask createTask( |
| 1158 AnalysisContext context, AnalysisTarget target) { | 1047 AnalysisContext context, AnalysisTarget target) { |
| 1159 return new BuildDirectiveElementsTask(context, target); | 1048 return new BuildDirectiveElementsTask(context, target); |
| 1160 } | 1049 } |
| 1161 | |
| 1162 /** | |
| 1163 * Build the element model representing the combinators declared by | |
| 1164 * the given [directive]. | |
| 1165 */ | |
| 1166 static List<NamespaceCombinator> _buildCombinators( | |
| 1167 NamespaceDirective directive) { | |
| 1168 List<NamespaceCombinator> combinators = <NamespaceCombinator>[]; | |
| 1169 for (Combinator combinator in directive.combinators) { | |
| 1170 if (combinator is ShowCombinator) { | |
| 1171 ShowElementCombinatorImpl show = new ShowElementCombinatorImpl(); | |
| 1172 show.offset = combinator.offset; | |
| 1173 show.end = combinator.end; | |
| 1174 show.shownNames = _getIdentifiers(combinator.shownNames); | |
| 1175 combinators.add(show); | |
| 1176 } else if (combinator is HideCombinator) { | |
| 1177 HideElementCombinatorImpl hide = new HideElementCombinatorImpl(); | |
| 1178 hide.hiddenNames = _getIdentifiers(combinator.hiddenNames); | |
| 1179 combinators.add(hide); | |
| 1180 } | |
| 1181 } | |
| 1182 return combinators; | |
| 1183 } | |
| 1184 | |
| 1185 /** | |
| 1186 * Return the lexical identifiers associated with the given [identifiers]. | |
| 1187 */ | |
| 1188 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { | |
| 1189 return identifiers.map((identifier) => identifier.name).toList(); | |
| 1190 } | |
| 1191 } | 1050 } |
| 1192 | 1051 |
| 1193 /** | 1052 /** |
| 1194 * A task that builds the elements representing the members of enum | 1053 * A task that builds the elements representing the members of enum |
| 1195 * declarations. | 1054 * declarations. |
| 1196 */ | 1055 */ |
| 1197 class BuildEnumMemberElementsTask extends SourceBasedAnalysisTask { | 1056 class BuildEnumMemberElementsTask extends SourceBasedAnalysisTask { |
| 1198 /** | 1057 /** |
| 1199 * The name of the [TYPE_PROVIDER] input. | 1058 * The name of the [TYPE_PROVIDER] input. |
| 1200 */ | 1059 */ |
| (...skipping 4277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5478 | 5337 |
| 5479 @override | 5338 @override |
| 5480 bool moveNext() { | 5339 bool moveNext() { |
| 5481 if (_newSources.isEmpty) { | 5340 if (_newSources.isEmpty) { |
| 5482 return false; | 5341 return false; |
| 5483 } | 5342 } |
| 5484 currentTarget = _newSources.removeLast(); | 5343 currentTarget = _newSources.removeLast(); |
| 5485 return true; | 5344 return true; |
| 5486 } | 5345 } |
| 5487 } | 5346 } |
| OLD | NEW |