| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'dart:core' hide Resource; | 7 import 'dart:core' hide Resource; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| 11 import 'package:analyzer/file_system/file_system.dart'; | 11 import 'package:analyzer/file_system/file_system.dart'; |
| 12 import 'package:analyzer/source/sdk_ext.dart'; |
| 12 import 'package:analyzer/src/dart/scanner/reader.dart'; | 13 import 'package:analyzer/src/dart/scanner/reader.dart'; |
| 13 import 'package:analyzer/src/dart/scanner/scanner.dart'; | 14 import 'package:analyzer/src/dart/scanner/scanner.dart'; |
| 14 import 'package:analyzer/src/generated/engine.dart'; | 15 import 'package:analyzer/src/generated/engine.dart'; |
| 15 import 'package:analyzer/src/generated/error.dart'; | 16 import 'package:analyzer/src/generated/error.dart'; |
| 16 import 'package:analyzer/src/generated/parser.dart'; | 17 import 'package:analyzer/src/generated/parser.dart'; |
| 17 import 'package:analyzer/src/generated/source.dart'; | 18 import 'package:analyzer/src/generated/source.dart'; |
| 19 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 18 import 'package:analyzer/src/summary/format.dart'; | 20 import 'package:analyzer/src/summary/format.dart'; |
| 19 import 'package:analyzer/src/summary/idl.dart'; | 21 import 'package:analyzer/src/summary/idl.dart'; |
| 20 import 'package:analyzer/src/summary/link.dart'; | 22 import 'package:analyzer/src/summary/link.dart'; |
| 21 import 'package:analyzer/src/summary/package_bundle_reader.dart' | 23 import 'package:analyzer/src/summary/package_bundle_reader.dart' |
| 22 show ResynthesizerResultProvider, SummaryDataStore; | 24 show ResynthesizerResultProvider, SummaryDataStore; |
| 23 import 'package:analyzer/src/summary/summarize_ast.dart' | 25 import 'package:analyzer/src/summary/summarize_ast.dart' |
| 24 show serializeAstUnlinked; | 26 show serializeAstUnlinked; |
| 25 import 'package:analyzer/src/summary/summarize_elements.dart' | 27 import 'package:analyzer/src/summary/summarize_elements.dart' |
| 26 show PackageBundleAssembler; | 28 show PackageBundleAssembler; |
| 27 import 'package:analyzer/src/util/fast_uri.dart'; | 29 import 'package:analyzer/src/util/fast_uri.dart'; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 _onUnlinkedCompleteCompleter ??= new Completer(); | 122 _onUnlinkedCompleteCompleter ??= new Completer(); |
| 121 return _onUnlinkedCompleteCompleter.future; | 123 return _onUnlinkedCompleteCompleter.future; |
| 122 } | 124 } |
| 123 | 125 |
| 124 /** | 126 /** |
| 125 * Return the [pathos.Context] corresponding to the [resourceProvider]. | 127 * Return the [pathos.Context] corresponding to the [resourceProvider]. |
| 126 */ | 128 */ |
| 127 pathos.Context get pathContext => resourceProvider.pathContext; | 129 pathos.Context get pathContext => resourceProvider.pathContext; |
| 128 | 130 |
| 129 /** | 131 /** |
| 132 * Compute and return the linked bundle for the SDK extension for the given |
| 133 * [context], or `null` if none of the packages has an SDK extension. At most |
| 134 * one extension library is supported, if more than one is found, then an |
| 135 * error will be logged, and `null` returned. |
| 136 */ |
| 137 PackageBundle computeSdkExtension( |
| 138 AnalysisContext context, PackageBundle sdkBundle) { |
| 139 // Prepare SDK extension library files. |
| 140 String libUriStr; |
| 141 String libPath; |
| 142 { |
| 143 Map<String, List<Folder>> packageMap = context.sourceFactory.packageMap; |
| 144 SdkExtUriResolver sdkExtUriResolver = new SdkExtUriResolver(packageMap); |
| 145 Map<String, String> sdkExtMappings = sdkExtUriResolver.urlMappings; |
| 146 if (sdkExtMappings.length == 1) { |
| 147 libUriStr = sdkExtMappings.keys.first; |
| 148 libPath = sdkExtMappings.values.first; |
| 149 } else if (sdkExtMappings.length > 1) { |
| 150 AnalysisEngine.instance.logger |
| 151 .logError('At most one _sdkext file is supported, ' |
| 152 'with at most one extension library. $sdkExtMappings found.'); |
| 153 return null; |
| 154 } else { |
| 155 return null; |
| 156 } |
| 157 } |
| 158 // Compute the extension unlinked bundle. |
| 159 bool strong = context.analysisOptions.strongMode; |
| 160 PackageBundleAssembler assembler = new PackageBundleAssembler(); |
| 161 try { |
| 162 File libFile = resourceProvider.getFile(libPath); |
| 163 Uri libUri = FastUri.parse(libUriStr); |
| 164 Source libSource = libFile.createSource(libUri); |
| 165 CompilationUnit libraryUnit = _parse(libSource, strong); |
| 166 // Add the library unit. |
| 167 assembler.addUnlinkedUnit(libSource, serializeAstUnlinked(libraryUnit)); |
| 168 // Add part units. |
| 169 for (Directive directive in libraryUnit.directives) { |
| 170 if (directive is PartDirective) { |
| 171 Source partSource; |
| 172 { |
| 173 String partUriStr = directive.uri.stringValue; |
| 174 Uri partUri = resolveRelativeUri(libUri, FastUri.parse(partUriStr)); |
| 175 pathos.Context pathContext = resourceProvider.pathContext; |
| 176 String partPath = |
| 177 pathContext.join(pathContext.dirname(libPath), partUriStr); |
| 178 File partFile = resourceProvider.getFile(partPath); |
| 179 partSource = partFile.createSource(partUri); |
| 180 } |
| 181 CompilationUnit partUnit = _parse(partSource, strong); |
| 182 assembler.addUnlinkedUnit(partSource, serializeAstUnlinked(partUnit)); |
| 183 } |
| 184 } |
| 185 // Add the SDK and the unlinked extension bundle. |
| 186 PackageBundleBuilder unlinkedBuilder = assembler.assemble(); |
| 187 SummaryDataStore store = new SummaryDataStore(const <String>[]); |
| 188 store.addBundle(null, sdkBundle); |
| 189 store.addBundle(null, unlinkedBuilder); |
| 190 // Link the extension bundle. |
| 191 bool failed = false; |
| 192 Map<String, LinkedLibraryBuilder> linkedLibraries = |
| 193 link([libUriStr].toSet(), (String absoluteUri) { |
| 194 LinkedLibrary dependencyLibrary = store.linkedMap[absoluteUri]; |
| 195 if (dependencyLibrary == null) { |
| 196 failed = true; |
| 197 } |
| 198 return dependencyLibrary; |
| 199 }, (String absoluteUri) { |
| 200 UnlinkedUnit unlinkedUnit = store.unlinkedMap[absoluteUri]; |
| 201 if (unlinkedUnit == null) { |
| 202 failed = true; |
| 203 } |
| 204 return unlinkedUnit; |
| 205 }, strong); |
| 206 if (failed || linkedLibraries.length != 1) { |
| 207 return null; |
| 208 } |
| 209 // Append linked libraries into the assembler. |
| 210 linkedLibraries.forEach((uri, library) { |
| 211 assembler.addLinkedLibrary(uri, library); |
| 212 }); |
| 213 List<int> bytes = assembler.assemble().toBuffer(); |
| 214 return new PackageBundle.fromBuffer(bytes); |
| 215 } on FileSystemException { |
| 216 return null; |
| 217 } |
| 218 } |
| 219 |
| 220 /** |
| 130 * Return the list of linked [LinkedPubPackage]s that can be provided at this | 221 * Return the list of linked [LinkedPubPackage]s that can be provided at this |
| 131 * time for a subset of the packages used by the given [context]. If | 222 * time for a subset of the packages used by the given [context]. If |
| 132 * information about some of the used packages is not available yet, schedule | 223 * information about some of the used packages is not available yet, schedule |
| 133 * its computation, so that it might be available later for other contexts | 224 * its computation, so that it might be available later for other contexts |
| 134 * referencing the same packages. | 225 * referencing the same packages. |
| 135 */ | 226 */ |
| 136 List<LinkedPubPackage> getLinkedBundles( | 227 List<LinkedPubPackage> getLinkedBundles( |
| 137 AnalysisContext context, PackageBundle sdkBundle) { | 228 AnalysisContext context, PackageBundle sdkBundle) { |
| 138 Map<PubPackage, PackageBundle> unlinkedBundles = | 229 Map<PubPackage, PackageBundle> unlinkedBundles = |
| 139 getUnlinkedBundles(context); | 230 getUnlinkedBundles(context); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 } | 277 } |
| 187 | 278 |
| 188 /** | 279 /** |
| 189 * Return all available unlinked [PackageBundle]s for the given [context], | 280 * Return all available unlinked [PackageBundle]s for the given [context], |
| 190 * maybe an empty map, but not `null`. | 281 * maybe an empty map, but not `null`. |
| 191 */ | 282 */ |
| 192 Map<PubPackage, PackageBundle> getUnlinkedBundles(AnalysisContext context) { | 283 Map<PubPackage, PackageBundle> getUnlinkedBundles(AnalysisContext context) { |
| 193 bool strong = context.analysisOptions.strongMode; | 284 bool strong = context.analysisOptions.strongMode; |
| 194 Map<PubPackage, PackageBundle> unlinkedBundles = | 285 Map<PubPackage, PackageBundle> unlinkedBundles = |
| 195 new HashMap<PubPackage, PackageBundle>(); | 286 new HashMap<PubPackage, PackageBundle>(); |
| 196 // TODO(scheglov) get _sdkext bundles. | |
| 197 Map<String, List<Folder>> packageMap = context.sourceFactory.packageMap; | 287 Map<String, List<Folder>> packageMap = context.sourceFactory.packageMap; |
| 198 if (packageMap != null) { | 288 if (packageMap != null) { |
| 199 packageMap.forEach((String packageName, List<Folder> libFolders) { | 289 packageMap.forEach((String packageName, List<Folder> libFolders) { |
| 200 if (libFolders.length == 1) { | 290 if (libFolders.length == 1) { |
| 201 Folder libFolder = libFolders.first; | 291 Folder libFolder = libFolders.first; |
| 202 // TODO(scheglov) handle Flutter packages, outside of the pub cache. | 292 // TODO(scheglov) handle Flutter packages, outside of the pub cache. |
| 203 if (isPathInPubCache(pathContext, libFolder.path)) { | 293 if (isPathInPubCache(pathContext, libFolder.path)) { |
| 204 PubPackage package = new PubPackage(packageName, libFolder); | 294 PubPackage package = new PubPackage(packageName, libFolder); |
| 205 PackageBundle unlinkedBundle = | 295 PackageBundle unlinkedBundle = |
| 206 _getUnlinkedOrSchedule(package, strong); | 296 _getUnlinkedOrSchedule(package, strong); |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 } | 600 } |
| 511 }); | 601 }); |
| 512 node.linkedBuilder = assembler.assemble(); | 602 node.linkedBuilder = assembler.assemble(); |
| 513 store.addBundle(null, node.linkedBuilder); | 603 store.addBundle(null, node.linkedBuilder); |
| 514 } | 604 } |
| 515 } else { | 605 } else { |
| 516 scc.forEach((node) => node.failed = true); | 606 scc.forEach((node) => node.failed = true); |
| 517 } | 607 } |
| 518 } | 608 } |
| 519 } | 609 } |
| OLD | NEW |