| 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/dart/ast/ast.dart' show CompilationUnit; | 10 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 final AnalysisStats stats; | 129 final AnalysisStats stats; |
| 130 | 130 |
| 131 SummaryDataStore summaryDataStore; | 131 SummaryDataStore summaryDataStore; |
| 132 InternalAnalysisContext context; | 132 InternalAnalysisContext context; |
| 133 Map<Uri, File> uriToFileMap; | 133 Map<Uri, File> uriToFileMap; |
| 134 final List<Source> explicitSources = <Source>[]; | 134 final List<Source> explicitSources = <Source>[]; |
| 135 final List<PackageBundle> unlinkedBundles = <PackageBundle>[]; | 135 final List<PackageBundle> unlinkedBundles = <PackageBundle>[]; |
| 136 | 136 |
| 137 PackageBundleAssembler assembler; | 137 PackageBundleAssembler assembler; |
| 138 final Set<Source> processedSources = new Set<Source>(); | 138 final Set<Source> processedSources = new Set<Source>(); |
| 139 final Map<Uri, UnlinkedUnit> uriToUnit = <Uri, UnlinkedUnit>{}; | 139 final Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{}; |
| 140 | 140 |
| 141 BuildMode(this.resourceProvider, this.options, this.stats); | 141 BuildMode(this.resourceProvider, this.options, this.stats); |
| 142 | 142 |
| 143 bool get _shouldOutputSummary => | 143 bool get _shouldOutputSummary => |
| 144 options.buildSummaryOutput != null || | 144 options.buildSummaryOutput != null || |
| 145 options.buildSummaryOutputSemantic != null; | 145 options.buildSummaryOutputSemantic != null; |
| 146 | 146 |
| 147 /** | 147 /** |
| 148 * Perform package analysis according to the given [options]. | 148 * Perform package analysis according to the given [options]. |
| 149 */ | 149 */ |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 AnalysisResult analysisResult = context.performAnalysisTask(); | 199 AnalysisResult analysisResult = context.performAnalysisTask(); |
| 200 if (!analysisResult.hasMoreWork) { | 200 if (!analysisResult.hasMoreWork) { |
| 201 break; | 201 break; |
| 202 } | 202 } |
| 203 } | 203 } |
| 204 } | 204 } |
| 205 | 205 |
| 206 // Write summary. | 206 // Write summary. |
| 207 assembler = new PackageBundleAssembler(); | 207 assembler = new PackageBundleAssembler(); |
| 208 if (_shouldOutputSummary) { | 208 if (_shouldOutputSummary) { |
| 209 if (options.buildSummaryOnlyUnlinked) { | 209 // Prepare all unlinked units. |
| 210 for (var src in explicitSources) { | 210 for (var src in explicitSources) { |
| 211 // Note: This adds the unit to the assembler if it needed to be | 211 _prepareUnlinkedUnit('${src.uri}'); |
| 212 // computed, so we don't need to explicitly do that. | 212 } |
| 213 _unlinkedUnitForUri('${src.uri}'); | 213 |
| 214 } | 214 // Build and assemble linked libraries. |
| 215 } else { | 215 if (!options.buildSummaryOnlyUnlinked) { |
| 216 Set<String> unlinkedUris = | 216 // Prepare URIs of unlinked units that should be linked. |
| 217 explicitSources.map((Source s) => s.uri.toString()).toSet(); | 217 var unlinkedUris = new Set<String>(); |
| 218 for (var bundle in unlinkedBundles) { | 218 for (var bundle in unlinkedBundles) { |
| 219 unlinkedUris.addAll(bundle.unlinkedUnitUris); | 219 unlinkedUris.addAll(bundle.unlinkedUnitUris); |
| 220 } | 220 } |
| 221 | 221 for (var src in explicitSources) { |
| 222 _serializeAstBasedSummary(unlinkedUris); | 222 unlinkedUris.add('${src.uri}'); |
| 223 } |
| 224 // Perform linking. |
| 225 _computeLinkedLibraries(unlinkedUris); |
| 223 assembler.recordDependencies(summaryDataStore); | 226 assembler.recordDependencies(summaryDataStore); |
| 224 } | 227 } |
| 228 |
| 225 // Write the whole package bundle. | 229 // Write the whole package bundle. |
| 226 PackageBundleBuilder bundle = assembler.assemble(); | 230 PackageBundleBuilder bundle = assembler.assemble(); |
| 227 if (options.buildSummaryOutput != null) { | 231 if (options.buildSummaryOutput != null) { |
| 228 io.File file = new io.File(options.buildSummaryOutput); | 232 io.File file = new io.File(options.buildSummaryOutput); |
| 229 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); | 233 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); |
| 230 } | 234 } |
| 231 if (options.buildSummaryOutputSemantic != null) { | 235 if (options.buildSummaryOutputSemantic != null) { |
| 232 bundle.flushInformative(); | 236 bundle.flushInformative(); |
| 233 io.File file = new io.File(options.buildSummaryOutputSemantic); | 237 io.File file = new io.File(options.buildSummaryOutputSemantic); |
| 234 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); | 238 file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); |
| 235 } | 239 } |
| 236 } | 240 } |
| 237 | 241 |
| 238 if (options.buildSummaryOnly) { | 242 if (options.buildSummaryOnly) { |
| 239 return ErrorSeverity.NONE; | 243 return ErrorSeverity.NONE; |
| 240 } else { | 244 } else { |
| 241 // Process errors. | 245 // Process errors. |
| 242 _printErrors(outputPath: options.buildAnalysisOutput); | 246 _printErrors(outputPath: options.buildAnalysisOutput); |
| 243 return _computeMaxSeverity(); | 247 return _computeMaxSeverity(); |
| 244 } | 248 } |
| 245 } | 249 } |
| 246 | 250 |
| 251 /** |
| 252 * Compute linked libraries for the given [libraryUris] using the linked |
| 253 * libraries of the [summaryDataStore] and unlinked units in [uriToUnit], and |
| 254 * add them to the [assembler]. |
| 255 */ |
| 256 void _computeLinkedLibraries(Set<String> libraryUris) { |
| 257 LinkedLibrary getDependency(String absoluteUri) => |
| 258 summaryDataStore.linkedMap[absoluteUri]; |
| 259 |
| 260 UnlinkedUnit getUnit(String absoluteUri) => |
| 261 summaryDataStore.unlinkedMap[absoluteUri] ?? uriToUnit[absoluteUri]; |
| 262 |
| 263 Map<String, LinkedLibraryBuilder> linkResult = link( |
| 264 libraryUris, |
| 265 getDependency, |
| 266 getUnit, |
| 267 context.declaredVariables.get, |
| 268 options.strongMode); |
| 269 linkResult.forEach(assembler.addLinkedLibrary); |
| 270 } |
| 271 |
| 247 ErrorSeverity _computeMaxSeverity() { | 272 ErrorSeverity _computeMaxSeverity() { |
| 248 ErrorSeverity maxSeverity = ErrorSeverity.NONE; | 273 ErrorSeverity maxSeverity = ErrorSeverity.NONE; |
| 249 if (!options.buildSuppressExitCode) { | 274 if (!options.buildSuppressExitCode) { |
| 250 for (Source source in explicitSources) { | 275 for (Source source in explicitSources) { |
| 251 AnalysisErrorInfo errorInfo = context.getErrors(source); | 276 AnalysisErrorInfo errorInfo = context.getErrors(source); |
| 252 for (AnalysisError error in errorInfo.errors) { | 277 for (AnalysisError error in errorInfo.errors) { |
| 253 ErrorSeverity processedSeverity = determineProcessedSeverity( | 278 ErrorSeverity processedSeverity = determineProcessedSeverity( |
| 254 error, options, context.analysisOptions); | 279 error, options, context.analysisOptions); |
| 255 if (processedSeverity != null) { | 280 if (processedSeverity != null) { |
| 256 maxSeverity = maxSeverity.max(processedSeverity); | 281 maxSeverity = maxSeverity.max(processedSeverity); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 return null; | 380 return null; |
| 356 } | 381 } |
| 357 Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex)); | 382 Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex)); |
| 358 String path = sourceFile.substring(pipeIndex + 1); | 383 String path = sourceFile.substring(pipeIndex + 1); |
| 359 uriToFileMap[uri] = resourceProvider.getFile(path); | 384 uriToFileMap[uri] = resourceProvider.getFile(path); |
| 360 } | 385 } |
| 361 return uriToFileMap; | 386 return uriToFileMap; |
| 362 } | 387 } |
| 363 | 388 |
| 364 /** | 389 /** |
| 390 * Ensure that the [UnlinkedUnit] for [absoluteUri] is available. |
| 391 * |
| 392 * If the unit is in the input [summaryDataStore], do nothing. |
| 393 * |
| 394 * Otherwise compute it and store into the [uriToUnit] and [assembler]. |
| 395 */ |
| 396 void _prepareUnlinkedUnit(String absoluteUri) { |
| 397 // Maybe an input package contains the source. |
| 398 if (summaryDataStore.unlinkedMap[absoluteUri] != null) { |
| 399 return; |
| 400 } |
| 401 // Parse the source and serialize its AST. |
| 402 Uri uri = Uri.parse(absoluteUri); |
| 403 Source source = context.sourceFactory.forUri2(uri); |
| 404 if (!source.exists()) { |
| 405 // TODO(paulberry): we should report a warning/error because DDC |
| 406 // compilations are unlikely to work. |
| 407 return; |
| 408 } |
| 409 CompilationUnit unit = context.computeResult(source, PARSED_UNIT); |
| 410 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit); |
| 411 uriToUnit[absoluteUri] = unlinkedUnit; |
| 412 assembler.addUnlinkedUnit(source, unlinkedUnit); |
| 413 } |
| 414 |
| 415 /** |
| 365 * Print errors for all explicit sources. If [outputPath] is supplied, output | 416 * Print errors for all explicit sources. If [outputPath] is supplied, output |
| 366 * is sent to a new file at that path. | 417 * is sent to a new file at that path. |
| 367 */ | 418 */ |
| 368 void _printErrors({String outputPath}) { | 419 void _printErrors({String outputPath}) { |
| 369 StringBuffer buffer = new StringBuffer(); | 420 StringBuffer buffer = new StringBuffer(); |
| 370 var severityProcessor = (AnalysisError error) => | 421 var severityProcessor = (AnalysisError error) => |
| 371 determineProcessedSeverity(error, options, context.analysisOptions); | 422 determineProcessedSeverity(error, options, context.analysisOptions); |
| 372 ErrorFormatter formatter = options.machineFormat | 423 ErrorFormatter formatter = options.machineFormat |
| 373 ? new MachineErrorFormatter(buffer, options, stats, | 424 ? new MachineErrorFormatter(buffer, options, stats, |
| 374 severityProcessor: severityProcessor) | 425 severityProcessor: severityProcessor) |
| 375 : new HumanErrorFormatter(buffer, options, stats, | 426 : new HumanErrorFormatter(buffer, options, stats, |
| 376 severityProcessor: severityProcessor); | 427 severityProcessor: severityProcessor); |
| 377 for (Source source in explicitSources) { | 428 for (Source source in explicitSources) { |
| 378 AnalysisErrorInfo errorInfo = context.getErrors(source); | 429 AnalysisErrorInfo errorInfo = context.getErrors(source); |
| 379 formatter.formatErrors([errorInfo]); | 430 formatter.formatErrors([errorInfo]); |
| 380 } | 431 } |
| 381 formatter.flush(); | 432 formatter.flush(); |
| 382 if (!options.machineFormat) { | 433 if (!options.machineFormat) { |
| 383 stats.print(buffer); | 434 stats.print(buffer); |
| 384 } | 435 } |
| 385 if (outputPath == null) { | 436 if (outputPath == null) { |
| 386 StringSink sink = options.machineFormat ? errorSink : outSink; | 437 StringSink sink = options.machineFormat ? errorSink : outSink; |
| 387 sink.write(buffer); | 438 sink.write(buffer); |
| 388 } else { | 439 } else { |
| 389 new io.File(outputPath).writeAsStringSync(buffer.toString()); | 440 new io.File(outputPath).writeAsStringSync(buffer.toString()); |
| 390 } | 441 } |
| 391 } | 442 } |
| 392 | |
| 393 /** | |
| 394 * Serialize the package with the given [sources] into [assembler] using only | |
| 395 * their ASTs and [LinkedUnit]s of input packages. | |
| 396 */ | |
| 397 void _serializeAstBasedSummary(Set<String> unlinkedUris) { | |
| 398 LinkedLibrary _getDependency(String absoluteUri) => | |
| 399 summaryDataStore.linkedMap[absoluteUri]; | |
| 400 | |
| 401 Map<String, LinkedLibraryBuilder> linkResult = link( | |
| 402 unlinkedUris, | |
| 403 _getDependency, | |
| 404 _unlinkedUnitForUri, | |
| 405 context.declaredVariables.get, | |
| 406 options.strongMode); | |
| 407 linkResult.forEach(assembler.addLinkedLibrary); | |
| 408 } | |
| 409 | |
| 410 /** | |
| 411 * Returns the [UnlinkedUnit] for [absoluteUri], either by computing it or | |
| 412 * using the stored one in [uriToUnit]. | |
| 413 * | |
| 414 * If the [UnlinkedUnit] needed to be computed, it will also be added to the | |
| 415 * [assembler]. | |
| 416 */ | |
| 417 UnlinkedUnit _unlinkedUnitForUri(String absoluteUri) { | |
| 418 // Maybe an input package contains the source. | |
| 419 { | |
| 420 UnlinkedUnit unlinkedUnit = summaryDataStore.unlinkedMap[absoluteUri]; | |
| 421 if (unlinkedUnit != null) { | |
| 422 return unlinkedUnit; | |
| 423 } | |
| 424 } | |
| 425 // Parse the source and serialize its AST. | |
| 426 Uri uri = Uri.parse(absoluteUri); | |
| 427 Source source = context.sourceFactory.forUri2(uri); | |
| 428 if (!source.exists()) { | |
| 429 // TODO(paulberry): we should report a warning/error because DDC | |
| 430 // compilations are unlikely to work. | |
| 431 return null; | |
| 432 } | |
| 433 return uriToUnit.putIfAbsent(uri, () { | |
| 434 CompilationUnit unit = context.computeResult(source, PARSED_UNIT); | |
| 435 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit); | |
| 436 assembler.addUnlinkedUnit(source, unlinkedUnit); | |
| 437 return unlinkedUnit; | |
| 438 }); | |
| 439 } | |
| 440 } | 443 } |
| 441 | 444 |
| 442 /** | 445 /** |
| 443 * Instances of the class [ExplicitSourceResolver] map URIs to files on disk | 446 * Instances of the class [ExplicitSourceResolver] map URIs to files on disk |
| 444 * using a fixed mapping provided at construction time. | 447 * using a fixed mapping provided at construction time. |
| 445 */ | 448 */ |
| 446 class ExplicitSourceResolver extends UriResolver { | 449 class ExplicitSourceResolver extends UriResolver { |
| 447 final Map<Uri, File> uriToFileMap; | 450 final Map<Uri, File> uriToFileMap; |
| 448 final Map<String, Uri> pathToUriMap; | 451 final Map<String, Uri> pathToUriMap; |
| 449 | 452 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 475 * Build the inverse mapping of [uriToSourceMap]. | 478 * Build the inverse mapping of [uriToSourceMap]. |
| 476 */ | 479 */ |
| 477 static Map<String, Uri> _computePathToUriMap(Map<Uri, File> uriToSourceMap) { | 480 static Map<String, Uri> _computePathToUriMap(Map<Uri, File> uriToSourceMap) { |
| 478 Map<String, Uri> pathToUriMap = <String, Uri>{}; | 481 Map<String, Uri> pathToUriMap = <String, Uri>{}; |
| 479 uriToSourceMap.forEach((Uri uri, File file) { | 482 uriToSourceMap.forEach((Uri uri, File file) { |
| 480 pathToUriMap[file.path] = uri; | 483 pathToUriMap[file.path] = uri; |
| 481 }); | 484 }); |
| 482 return pathToUriMap; | 485 return pathToUriMap; |
| 483 } | 486 } |
| 484 } | 487 } |
| OLD | NEW |