| 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_cli.src.build_mode; | 5 library analyzer_cli.src.build_mode; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io' as io; | 8 import 'dart:io' as io; |
| 9 | 9 |
| 10 import 'package:analyzer/error/error.dart'; | 10 import 'package:analyzer/error/error.dart'; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 /** | 127 /** |
| 128 * Analyzer used when the "--build-mode" option is supplied. | 128 * Analyzer used when the "--build-mode" option is supplied. |
| 129 */ | 129 */ |
| 130 class BuildMode { | 130 class BuildMode { |
| 131 final ResourceProvider resourceProvider; | 131 final ResourceProvider resourceProvider; |
| 132 final CommandLineOptions options; | 132 final CommandLineOptions options; |
| 133 final AnalysisStats stats; | 133 final AnalysisStats stats; |
| 134 | 134 |
| 135 SummaryDataStore summaryDataStore; | 135 SummaryDataStore summaryDataStore; |
| 136 AnalysisOptions analysisOptions; | 136 AnalysisOptions analysisOptions; |
| 137 AnalysisDriver analysisDriver; | |
| 138 Map<Uri, File> uriToFileMap; | 137 Map<Uri, File> uriToFileMap; |
| 139 final List<Source> explicitSources = <Source>[]; | 138 final List<Source> explicitSources = <Source>[]; |
| 140 final List<PackageBundle> unlinkedBundles = <PackageBundle>[]; | 139 final List<PackageBundle> unlinkedBundles = <PackageBundle>[]; |
| 141 | 140 |
| 141 PerformanceLog logger = new PerformanceLog(null); |
| 142 AnalysisDriver analysisDriver; |
| 143 |
| 142 PackageBundleAssembler assembler; | 144 PackageBundleAssembler assembler; |
| 143 final Set<Source> processedSources = new Set<Source>(); | 145 final Set<Source> processedSources = new Set<Source>(); |
| 144 final Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{}; | 146 final Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{}; |
| 145 | 147 |
| 146 BuildMode(this.resourceProvider, this.options, this.stats); | 148 BuildMode(this.resourceProvider, this.options, this.stats); |
| 147 | 149 |
| 148 bool get _shouldOutputSummary => | 150 bool get _shouldOutputSummary => |
| 149 options.buildSummaryOutput != null || | 151 options.buildSummaryOutput != null || |
| 150 options.buildSummaryOutputSemantic != null; | 152 options.buildSummaryOutputSemantic != null; |
| 151 | 153 |
| 152 /** | 154 /** |
| 153 * Perform package analysis according to the given [options]. | 155 * Perform package analysis according to the given [options]. |
| 154 */ | 156 */ |
| 155 Future<ErrorSeverity> analyze() async { | 157 Future<ErrorSeverity> analyze() async { |
| 156 // Write initial progress message. | 158 return await logger.runAsync('Analyze', () async { |
| 157 if (!options.machineFormat) { | 159 // Write initial progress message. |
| 158 outSink.writeln("Analyzing ${options.sourceFiles.join(', ')}..."); | 160 if (!options.machineFormat) { |
| 159 } | 161 outSink.writeln("Analyzing ${options.sourceFiles.join(', ')}..."); |
| 162 } |
| 160 | 163 |
| 161 // Create the URI to file map. | 164 // Create the URI to file map. |
| 162 uriToFileMap = _createUriToFileMap(options.sourceFiles); | 165 uriToFileMap = _createUriToFileMap(options.sourceFiles); |
| 163 if (uriToFileMap == null) { | 166 if (uriToFileMap == null) { |
| 164 io.exitCode = ErrorSeverity.ERROR.ordinal; | |
| 165 return ErrorSeverity.ERROR; | |
| 166 } | |
| 167 | |
| 168 // BuildMode expects sourceFiles in the format "<uri>|<filepath>", | |
| 169 // but the rest of the code base does not understand this format. | |
| 170 // Rewrite sourceFiles, stripping the "<uri>|" prefix, so that it | |
| 171 // does not cause problems with code that does not expect this format. | |
| 172 options.rewriteSourceFiles(options.sourceFiles | |
| 173 .map((String uriPipePath) => | |
| 174 uriPipePath.substring(uriPipePath.indexOf('|') + 1)) | |
| 175 .toList()); | |
| 176 | |
| 177 // Prepare the analysis driver. | |
| 178 try { | |
| 179 _createAnalysisDriver(); | |
| 180 } on ConflictingSummaryException catch (e) { | |
| 181 errorSink.writeln('$e'); | |
| 182 io.exitCode = ErrorSeverity.ERROR.ordinal; | |
| 183 return ErrorSeverity.ERROR; | |
| 184 } | |
| 185 | |
| 186 // Add sources. | |
| 187 for (Uri uri in uriToFileMap.keys) { | |
| 188 File file = uriToFileMap[uri]; | |
| 189 if (!file.exists) { | |
| 190 errorSink.writeln('File not found: ${file.path}'); | |
| 191 io.exitCode = ErrorSeverity.ERROR.ordinal; | 167 io.exitCode = ErrorSeverity.ERROR.ordinal; |
| 192 return ErrorSeverity.ERROR; | 168 return ErrorSeverity.ERROR; |
| 193 } | 169 } |
| 194 Source source = new FileSource(file, uri); | |
| 195 explicitSources.add(source); | |
| 196 } | |
| 197 | 170 |
| 198 // Write summary. | 171 // BuildMode expects sourceFiles in the format "<uri>|<filepath>", |
| 199 assembler = new PackageBundleAssembler(); | 172 // but the rest of the code base does not understand this format. |
| 200 if (_shouldOutputSummary) { | 173 // Rewrite sourceFiles, stripping the "<uri>|" prefix, so that it |
| 201 // Prepare all unlinked units. | 174 // does not cause problems with code that does not expect this format. |
| 202 for (var src in explicitSources) { | 175 options.rewriteSourceFiles(options.sourceFiles |
| 203 await _prepareUnlinkedUnit('${src.uri}'); | 176 .map((String uriPipePath) => |
| 177 uriPipePath.substring(uriPipePath.indexOf('|') + 1)) |
| 178 .toList()); |
| 179 |
| 180 // Prepare the analysis driver. |
| 181 try { |
| 182 logger.run('Prepare analysis driver', () { |
| 183 _createAnalysisDriver(); |
| 184 }); |
| 185 } on ConflictingSummaryException catch (e) { |
| 186 errorSink.writeln('$e'); |
| 187 io.exitCode = ErrorSeverity.ERROR.ordinal; |
| 188 return ErrorSeverity.ERROR; |
| 204 } | 189 } |
| 205 | 190 |
| 206 // Build and assemble linked libraries. | 191 // Add sources. |
| 207 if (!options.buildSummaryOnlyUnlinked) { | 192 for (Uri uri in uriToFileMap.keys) { |
| 208 // Prepare URIs of unlinked units that should be linked. | 193 File file = uriToFileMap[uri]; |
| 209 var unlinkedUris = new Set<String>(); | 194 if (!file.exists) { |
| 210 for (var bundle in unlinkedBundles) { | 195 errorSink.writeln('File not found: ${file.path}'); |
| 211 unlinkedUris.addAll(bundle.unlinkedUnitUris); | 196 io.exitCode = ErrorSeverity.ERROR.ordinal; |
| 197 return ErrorSeverity.ERROR; |
| 212 } | 198 } |
| 213 for (var src in explicitSources) { | 199 Source source = new FileSource(file, uri); |
| 214 unlinkedUris.add('${src.uri}'); | 200 explicitSources.add(source); |
| 215 } | |
| 216 // Perform linking. | |
| 217 _computeLinkedLibraries(unlinkedUris); | |
| 218 assembler.recordDependencies(summaryDataStore); | |
| 219 } | 201 } |
| 220 | 202 |
| 221 // Write the whole package bundle. | 203 // Write summary. |
| 222 PackageBundleBuilder bundle = assembler.assemble(); | 204 assembler = new PackageBundleAssembler(); |
| 223 if (options.buildSummaryOutput != null) { | 205 if (_shouldOutputSummary) { |
| 224 io.File file = new io.File(options.buildSummaryOutput); | 206 await logger.runAsync('Build and write output summary', () async { |
| 225 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); | 207 // Prepare all unlinked units. |
| 208 await logger.runAsync('Prepare unlinked units', () async { |
| 209 for (var src in explicitSources) { |
| 210 await _prepareUnlinkedUnit('${src.uri}'); |
| 211 } |
| 212 }); |
| 213 |
| 214 // Build and assemble linked libraries. |
| 215 if (!options.buildSummaryOnlyUnlinked) { |
| 216 // Prepare URIs of unlinked units that should be linked. |
| 217 var unlinkedUris = new Set<String>(); |
| 218 for (var bundle in unlinkedBundles) { |
| 219 unlinkedUris.addAll(bundle.unlinkedUnitUris); |
| 220 } |
| 221 for (var src in explicitSources) { |
| 222 unlinkedUris.add('${src.uri}'); |
| 223 } |
| 224 // Perform linking. |
| 225 _computeLinkedLibraries(unlinkedUris); |
| 226 assembler.recordDependencies(summaryDataStore); |
| 227 } |
| 228 |
| 229 // Write the whole package bundle. |
| 230 PackageBundleBuilder bundle = assembler.assemble(); |
| 231 if (options.buildSummaryOutput != null) { |
| 232 io.File file = new io.File(options.buildSummaryOutput); |
| 233 file.writeAsBytesSync(bundle.toBuffer(), |
| 234 mode: io.FileMode.WRITE_ONLY); |
| 235 } |
| 236 if (options.buildSummaryOutputSemantic != null) { |
| 237 bundle.flushInformative(); |
| 238 io.File file = new io.File(options.buildSummaryOutputSemantic); |
| 239 file.writeAsBytesSync(bundle.toBuffer(), |
| 240 mode: io.FileMode.WRITE_ONLY); |
| 241 } |
| 242 }); |
| 226 } | 243 } |
| 227 if (options.buildSummaryOutputSemantic != null) { | 244 |
| 228 bundle.flushInformative(); | 245 if (options.buildSummaryOnly) { |
| 229 io.File file = new io.File(options.buildSummaryOutputSemantic); | 246 return ErrorSeverity.NONE; |
| 230 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); | 247 } else { |
| 248 // Process errors. |
| 249 await _printErrors(outputPath: options.buildAnalysisOutput); |
| 250 return await _computeMaxSeverity(); |
| 231 } | 251 } |
| 232 } | 252 }); |
| 233 | |
| 234 if (options.buildSummaryOnly) { | |
| 235 return ErrorSeverity.NONE; | |
| 236 } else { | |
| 237 // Process errors. | |
| 238 await _printErrors(outputPath: options.buildAnalysisOutput); | |
| 239 return await _computeMaxSeverity(); | |
| 240 } | |
| 241 } | 253 } |
| 242 | 254 |
| 243 /** | 255 /** |
| 244 * Compute linked libraries for the given [libraryUris] using the linked | 256 * Compute linked libraries for the given [libraryUris] using the linked |
| 245 * libraries of the [summaryDataStore] and unlinked units in [uriToUnit], and | 257 * libraries of the [summaryDataStore] and unlinked units in [uriToUnit], and |
| 246 * add them to the [assembler]. | 258 * add them to the [assembler]. |
| 247 */ | 259 */ |
| 248 void _computeLinkedLibraries(Set<String> libraryUris) { | 260 void _computeLinkedLibraries(Set<String> libraryUris) { |
| 249 LinkedLibrary getDependency(String absoluteUri) => | 261 logger.run('Link output summary', () { |
| 250 summaryDataStore.linkedMap[absoluteUri]; | 262 LinkedLibrary getDependency(String absoluteUri) => |
| 263 summaryDataStore.linkedMap[absoluteUri]; |
| 251 | 264 |
| 252 UnlinkedUnit getUnit(String absoluteUri) => | 265 UnlinkedUnit getUnit(String absoluteUri) => |
| 253 summaryDataStore.unlinkedMap[absoluteUri] ?? uriToUnit[absoluteUri]; | 266 summaryDataStore.unlinkedMap[absoluteUri] ?? uriToUnit[absoluteUri]; |
| 254 | 267 |
| 255 Map<String, LinkedLibraryBuilder> linkResult = link( | 268 Map<String, LinkedLibraryBuilder> linkResult = link( |
| 256 libraryUris, | 269 libraryUris, |
| 257 getDependency, | 270 getDependency, |
| 258 getUnit, | 271 getUnit, |
| 259 analysisDriver.declaredVariables.get, | 272 analysisDriver.declaredVariables.get, |
| 260 options.strongMode); | 273 options.strongMode); |
| 261 linkResult.forEach(assembler.addLinkedLibrary); | 274 linkResult.forEach(assembler.addLinkedLibrary); |
| 275 }); |
| 262 } | 276 } |
| 263 | 277 |
| 264 Future<ErrorSeverity> _computeMaxSeverity() async { | 278 Future<ErrorSeverity> _computeMaxSeverity() async { |
| 265 ErrorSeverity maxSeverity = ErrorSeverity.NONE; | 279 ErrorSeverity maxSeverity = ErrorSeverity.NONE; |
| 266 if (!options.buildSuppressExitCode) { | 280 if (!options.buildSuppressExitCode) { |
| 267 for (Source source in explicitSources) { | 281 for (Source source in explicitSources) { |
| 268 ErrorsResult result = await analysisDriver.getErrors(source.fullName); | 282 ErrorsResult result = await analysisDriver.getErrors(source.fullName); |
| 269 for (AnalysisError error in result.errors) { | 283 for (AnalysisError error in result.errors) { |
| 270 ErrorSeverity processedSeverity = determineProcessedSeverity( | 284 ErrorSeverity processedSeverity = determineProcessedSeverity( |
| 271 error, options, analysisDriver.analysisOptions); | 285 error, options, analysisDriver.analysisOptions); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 284 recordDependencyInfo: _shouldOutputSummary); | 298 recordDependencyInfo: _shouldOutputSummary); |
| 285 | 299 |
| 286 // Adds a bundle at `path` to `summaryDataStore`. | 300 // Adds a bundle at `path` to `summaryDataStore`. |
| 287 PackageBundle addBundle(String path) { | 301 PackageBundle addBundle(String path) { |
| 288 var bundle = | 302 var bundle = |
| 289 new PackageBundle.fromBuffer(new io.File(path).readAsBytesSync()); | 303 new PackageBundle.fromBuffer(new io.File(path).readAsBytesSync()); |
| 290 summaryDataStore.addBundle(path, bundle); | 304 summaryDataStore.addBundle(path, bundle); |
| 291 return bundle; | 305 return bundle; |
| 292 } | 306 } |
| 293 | 307 |
| 294 for (var path in options.buildSummaryInputs) { | 308 int numInputs = options.buildSummaryInputs.length + |
| 295 var bundle = addBundle(path); | 309 options.buildSummaryUnlinkedInputs.length; |
| 296 if (bundle.linkedLibraryUris.isEmpty && | 310 logger.run('Add $numInputs input summaries', () { |
| 297 bundle.unlinkedUnitUris.isNotEmpty) { | 311 for (var path in options.buildSummaryInputs) { |
| 298 throw new ArgumentError( | 312 var bundle = addBundle(path); |
| 299 'Got an unlinked summary for --build-summary-input at `$path`. ' | 313 if (bundle.linkedLibraryUris.isEmpty && |
| 300 'Unlinked summaries should be provided with the ' | 314 bundle.unlinkedUnitUris.isNotEmpty) { |
| 301 '--build-summary-unlinked-input argument.'); | 315 throw new ArgumentError( |
| 316 'Got an unlinked summary for --build-summary-input at `$path`. ' |
| 317 'Unlinked summaries should be provided with the ' |
| 318 '--build-summary-unlinked-input argument.'); |
| 319 } |
| 302 } | 320 } |
| 303 } | |
| 304 | 321 |
| 305 for (var path in options.buildSummaryUnlinkedInputs) { | 322 for (var path in options.buildSummaryUnlinkedInputs) { |
| 306 var bundle = addBundle(path); | 323 var bundle = addBundle(path); |
| 307 unlinkedBundles.add(bundle); | 324 unlinkedBundles.add(bundle); |
| 308 if (bundle.linkedLibraryUris.isNotEmpty) { | 325 if (bundle.linkedLibraryUris.isNotEmpty) { |
| 309 throw new ArgumentError( | 326 throw new ArgumentError( |
| 310 'Got a linked summary for --build-summary-input-unlinked at `$path`' | 327 'Got a linked summary for --build-summary-input-unlinked at `$path
`' |
| 311 '. Linked bundles should be provided with the ' | 328 '. Linked bundles should be provided with the ' |
| 312 '--build-summary-input argument.'); | 329 '--build-summary-input argument.'); |
| 330 } |
| 313 } | 331 } |
| 314 } | 332 }); |
| 315 | 333 |
| 316 DartSdk sdk; | 334 DartSdk sdk; |
| 317 PackageBundle sdkBundle; | 335 logger.run('Add SDK bundle', () { |
| 318 if (options.dartSdkSummaryPath != null) { | 336 PackageBundle sdkBundle; |
| 319 SummaryBasedDartSdk summarySdk = new SummaryBasedDartSdk( | 337 if (options.dartSdkSummaryPath != null) { |
| 320 options.dartSdkSummaryPath, options.strongMode); | 338 SummaryBasedDartSdk summarySdk = new SummaryBasedDartSdk( |
| 321 sdk = summarySdk; | 339 options.dartSdkSummaryPath, options.strongMode); |
| 322 sdkBundle = summarySdk.bundle; | 340 sdk = summarySdk; |
| 323 } else { | 341 sdkBundle = summarySdk.bundle; |
| 324 FolderBasedDartSdk dartSdk = new FolderBasedDartSdk(resourceProvider, | 342 } else { |
| 325 resourceProvider.getFolder(options.dartSdkPath), options.strongMode); | 343 FolderBasedDartSdk dartSdk = new FolderBasedDartSdk( |
| 326 dartSdk.analysisOptions = | 344 resourceProvider, |
| 327 Driver.createAnalysisOptionsForCommandLineOptions( | 345 resourceProvider.getFolder(options.dartSdkPath), |
| 328 resourceProvider, options); | 346 options.strongMode); |
| 329 dartSdk.useSummary = !options.buildSummaryOnly; | 347 dartSdk.analysisOptions = |
| 330 sdk = dartSdk; | 348 Driver.createAnalysisOptionsForCommandLineOptions( |
| 331 sdkBundle = dartSdk.getSummarySdkBundle(options.strongMode); | 349 resourceProvider, options); |
| 332 } | 350 dartSdk.useSummary = !options.buildSummaryOnly; |
| 351 sdk = dartSdk; |
| 352 sdkBundle = dartSdk.getSummarySdkBundle(options.strongMode); |
| 353 } |
| 333 | 354 |
| 334 // Include SDK bundle to avoid parsing SDK sources. | 355 // Include SDK bundle to avoid parsing SDK sources. |
| 335 summaryDataStore.addBundle(null, sdkBundle); | 356 summaryDataStore.addBundle(null, sdkBundle); |
| 357 }); |
| 336 | 358 |
| 337 var sourceFactory = new SourceFactory(<UriResolver>[ | 359 var sourceFactory = new SourceFactory(<UriResolver>[ |
| 338 new DartUriResolver(sdk), | 360 new DartUriResolver(sdk), |
| 339 new InSummaryUriResolver(resourceProvider, summaryDataStore), | 361 new InSummaryUriResolver(resourceProvider, summaryDataStore), |
| 340 new ExplicitSourceResolver(uriToFileMap) | 362 new ExplicitSourceResolver(uriToFileMap) |
| 341 ]); | 363 ]); |
| 342 | 364 |
| 343 analysisOptions = Driver.createAnalysisOptionsForCommandLineOptions( | 365 analysisOptions = Driver.createAnalysisOptionsForCommandLineOptions( |
| 344 resourceProvider, options); | 366 resourceProvider, options); |
| 345 | 367 |
| 346 PerformanceLog logger = new PerformanceLog(null); | |
| 347 AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(logger); | 368 AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(logger); |
| 348 analysisDriver = new AnalysisDriver( | 369 analysisDriver = new AnalysisDriver( |
| 349 scheduler, | 370 scheduler, |
| 350 logger, | 371 logger, |
| 351 resourceProvider, | 372 resourceProvider, |
| 352 new MemoryByteStore(), | 373 new MemoryByteStore(), |
| 353 new FileContentOverlay(), | 374 new FileContentOverlay(), |
| 354 null, | 375 null, |
| 355 sourceFactory, | 376 sourceFactory, |
| 356 analysisOptions, | 377 analysisOptions, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(result.unit); | 427 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(result.unit); |
| 407 uriToUnit[absoluteUri] = unlinkedUnit; | 428 uriToUnit[absoluteUri] = unlinkedUnit; |
| 408 assembler.addUnlinkedUnit(source, unlinkedUnit); | 429 assembler.addUnlinkedUnit(source, unlinkedUnit); |
| 409 } | 430 } |
| 410 | 431 |
| 411 /** | 432 /** |
| 412 * Print errors for all explicit sources. If [outputPath] is supplied, output | 433 * Print errors for all explicit sources. If [outputPath] is supplied, output |
| 413 * is sent to a new file at that path. | 434 * is sent to a new file at that path. |
| 414 */ | 435 */ |
| 415 Future<Null> _printErrors({String outputPath}) async { | 436 Future<Null> _printErrors({String outputPath}) async { |
| 416 StringBuffer buffer = new StringBuffer(); | 437 await logger.runAsync('Compute and print analysis errors', () async { |
| 417 var severityProcessor = (AnalysisError error) => | 438 StringBuffer buffer = new StringBuffer(); |
| 418 determineProcessedSeverity(error, options, analysisOptions); | 439 var severityProcessor = (AnalysisError error) => |
| 419 ErrorFormatter formatter = options.machineFormat | 440 determineProcessedSeverity(error, options, analysisOptions); |
| 420 ? new MachineErrorFormatter(buffer, options, stats, | 441 ErrorFormatter formatter = options.machineFormat |
| 421 severityProcessor: severityProcessor) | 442 ? new MachineErrorFormatter(buffer, options, stats, |
| 422 : new HumanErrorFormatter(buffer, options, stats, | 443 severityProcessor: severityProcessor) |
| 423 severityProcessor: severityProcessor); | 444 : new HumanErrorFormatter(buffer, options, stats, |
| 424 for (Source source in explicitSources) { | 445 severityProcessor: severityProcessor); |
| 425 var result = await analysisDriver.getErrors(source.fullName); | 446 for (Source source in explicitSources) { |
| 426 var errorInfo = new AnalysisErrorInfoImpl(result.errors, result.lineInfo); | 447 var result = await analysisDriver.getErrors(source.fullName); |
| 427 formatter.formatErrors([errorInfo]); | 448 var errorInfo = |
| 428 } | 449 new AnalysisErrorInfoImpl(result.errors, result.lineInfo); |
| 429 formatter.flush(); | 450 formatter.formatErrors([errorInfo]); |
| 430 if (!options.machineFormat) { | 451 } |
| 431 stats.print(buffer); | 452 formatter.flush(); |
| 432 } | 453 if (!options.machineFormat) { |
| 433 if (outputPath == null) { | 454 stats.print(buffer); |
| 434 StringSink sink = options.machineFormat ? errorSink : outSink; | 455 } |
| 435 sink.write(buffer); | 456 if (outputPath == null) { |
| 436 } else { | 457 StringSink sink = options.machineFormat ? errorSink : outSink; |
| 437 new io.File(outputPath).writeAsStringSync(buffer.toString()); | 458 sink.write(buffer); |
| 438 } | 459 } else { |
| 460 new io.File(outputPath).writeAsStringSync(buffer.toString()); |
| 461 } |
| 462 }); |
| 439 } | 463 } |
| 440 } | 464 } |
| 441 | 465 |
| 442 /** | 466 /** |
| 443 * Instances of the class [ExplicitSourceResolver] map URIs to files on disk | 467 * Instances of the class [ExplicitSourceResolver] map URIs to files on disk |
| 444 * using a fixed mapping provided at construction time. | 468 * using a fixed mapping provided at construction time. |
| 445 */ | 469 */ |
| 446 class ExplicitSourceResolver extends UriResolver { | 470 class ExplicitSourceResolver extends UriResolver { |
| 447 final Map<Uri, File> uriToFileMap; | 471 final Map<Uri, File> uriToFileMap; |
| 448 final Map<String, Uri> pathToUriMap; | 472 final Map<String, Uri> pathToUriMap; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 475 * Build the inverse mapping of [uriToSourceMap]. | 499 * Build the inverse mapping of [uriToSourceMap]. |
| 476 */ | 500 */ |
| 477 static Map<String, Uri> _computePathToUriMap(Map<Uri, File> uriToSourceMap) { | 501 static Map<String, Uri> _computePathToUriMap(Map<Uri, File> uriToSourceMap) { |
| 478 Map<String, Uri> pathToUriMap = <String, Uri>{}; | 502 Map<String, Uri> pathToUriMap = <String, Uri>{}; |
| 479 uriToSourceMap.forEach((Uri uri, File file) { | 503 uriToSourceMap.forEach((Uri uri, File file) { |
| 480 pathToUriMap[file.path] = uri; | 504 pathToUriMap[file.path] = uri; |
| 481 }); | 505 }); |
| 482 return pathToUriMap; | 506 return pathToUriMap; |
| 483 } | 507 } |
| 484 } | 508 } |
| OLD | NEW |