| 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:core' hide Resource; | 7 import 'dart:core' hide Resource; |
| 8 import 'dart:io' as io; | 8 import 'dart:io' as io; |
| 9 | 9 |
| 10 import 'package:protobuf/protobuf.dart'; | |
| 11 | |
| 12 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit; | 10 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit; |
| 13 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
| 14 import 'package:analyzer/file_system/file_system.dart'; | 12 import 'package:analyzer/file_system/file_system.dart'; |
| 15 import 'package:analyzer/file_system/physical_file_system.dart'; | 13 import 'package:analyzer/file_system/physical_file_system.dart'; |
| 16 import 'package:analyzer/src/generated/engine.dart'; | 14 import 'package:analyzer/src/generated/engine.dart'; |
| 17 import 'package:analyzer/src/generated/error.dart'; | 15 import 'package:analyzer/src/generated/error.dart'; |
| 18 import 'package:analyzer/src/generated/java_io.dart'; | 16 import 'package:analyzer/src/generated/java_io.dart'; |
| 19 import 'package:analyzer/src/generated/sdk_io.dart'; | 17 import 'package:analyzer/src/generated/sdk_io.dart'; |
| 20 import 'package:analyzer/src/generated/source.dart'; | 18 import 'package:analyzer/src/generated/source.dart'; |
| 21 import 'package:analyzer/src/generated/source_io.dart'; | 19 import 'package:analyzer/src/generated/source_io.dart'; |
| 22 import 'package:analyzer/src/summary/format.dart'; | 20 import 'package:analyzer/src/summary/format.dart'; |
| 23 import 'package:analyzer/src/summary/idl.dart'; | 21 import 'package:analyzer/src/summary/idl.dart'; |
| 22 import 'package:analyzer/src/summary/link.dart'; |
| 24 import 'package:analyzer/src/summary/package_bundle_reader.dart'; | 23 import 'package:analyzer/src/summary/package_bundle_reader.dart'; |
| 25 import 'package:analyzer/src/summary/prelink.dart'; | |
| 26 import 'package:analyzer/src/summary/summarize_ast.dart'; | 24 import 'package:analyzer/src/summary/summarize_ast.dart'; |
| 27 import 'package:analyzer/src/summary/summarize_elements.dart'; | 25 import 'package:analyzer/src/summary/summarize_elements.dart'; |
| 28 import 'package:analyzer/task/dart.dart'; | 26 import 'package:analyzer/task/dart.dart'; |
| 29 import 'package:analyzer_cli/src/analyzer_impl.dart'; | 27 import 'package:analyzer_cli/src/analyzer_impl.dart'; |
| 30 import 'package:analyzer_cli/src/driver.dart'; | 28 import 'package:analyzer_cli/src/driver.dart'; |
| 31 import 'package:analyzer_cli/src/error_formatter.dart'; | 29 import 'package:analyzer_cli/src/error_formatter.dart'; |
| 32 import 'package:analyzer_cli/src/options.dart'; | 30 import 'package:analyzer_cli/src/options.dart'; |
| 31 import 'package:protobuf/protobuf.dart'; |
| 33 | 32 |
| 34 import 'message_grouper.dart'; | 33 import 'message_grouper.dart'; |
| 35 import 'worker_protocol.pb.dart'; | 34 import 'worker_protocol.pb.dart'; |
| 36 | 35 |
| 37 /** | 36 /** |
| 38 * Analyzer used when the "--build-mode" option is supplied. | 37 * Analyzer used when the "--build-mode" option is supplied. |
| 39 */ | 38 */ |
| 40 class BuildMode { | 39 class BuildMode { |
| 41 final CommandLineOptions options; | 40 final CommandLineOptions options; |
| 42 final AnalysisStats stats; | 41 final AnalysisStats stats; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 while (true) { | 91 while (true) { |
| 93 AnalysisResult analysisResult = context.performAnalysisTask(); | 92 AnalysisResult analysisResult = context.performAnalysisTask(); |
| 94 if (!analysisResult.hasMoreWork) { | 93 if (!analysisResult.hasMoreWork) { |
| 95 break; | 94 break; |
| 96 } | 95 } |
| 97 } | 96 } |
| 98 } | 97 } |
| 99 | 98 |
| 100 // Write summary. | 99 // Write summary. |
| 101 if (options.buildSummaryOutput != null) { | 100 if (options.buildSummaryOutput != null) { |
| 102 for (Source source in explicitSources) { | 101 if (options.buildSummaryOnlyAst && !options.buildSummaryFallback) { |
| 103 if (context.computeKindOf(source) == SourceKind.LIBRARY) { | 102 _serializeAstBasedSummary(explicitSources); |
| 103 } else { |
| 104 for (Source source in explicitSources) { |
| 105 if (context.computeKindOf(source) == SourceKind.LIBRARY) { |
| 106 if (options.buildSummaryFallback) { |
| 107 assembler.addFallbackLibrary(source); |
| 108 } else { |
| 109 LibraryElement libraryElement = |
| 110 context.computeLibraryElement(source); |
| 111 assembler.serializeLibraryElement(libraryElement); |
| 112 } |
| 113 } |
| 104 if (options.buildSummaryFallback) { | 114 if (options.buildSummaryFallback) { |
| 105 assembler.addFallbackLibrary(source); | 115 assembler.addFallbackUnit(source); |
| 106 } else if (options.buildSummaryOnlyAst) { | |
| 107 _serializeAstBasedSummary(source); | |
| 108 } else { | |
| 109 LibraryElement libraryElement = | |
| 110 context.computeLibraryElement(source); | |
| 111 assembler.serializeLibraryElement(libraryElement); | |
| 112 } | 116 } |
| 113 } | 117 } |
| 114 if (options.buildSummaryFallback) { | |
| 115 assembler.addFallbackUnit(source); | |
| 116 } | |
| 117 } | 118 } |
| 118 // Write the whole package bundle. | 119 // Write the whole package bundle. |
| 119 PackageBundleBuilder sdkBundle = assembler.assemble(); | 120 PackageBundleBuilder sdkBundle = assembler.assemble(); |
| 120 if (options.buildSummaryExcludeInformative) { | 121 if (options.buildSummaryExcludeInformative) { |
| 121 sdkBundle.flushInformative(); | 122 sdkBundle.flushInformative(); |
| 122 sdkBundle.unlinkedUnitHashes = null; | 123 sdkBundle.unlinkedUnitHashes = null; |
| 123 } | 124 } |
| 124 io.File file = new io.File(options.buildSummaryOutput); | 125 io.File file = new io.File(options.buildSummaryOutput); |
| 125 file.writeAsBytesSync(sdkBundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); | 126 file.writeAsBytesSync(sdkBundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); |
| 126 } | 127 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 } | 210 } |
| 210 if (outputPath == null) { | 211 if (outputPath == null) { |
| 211 StringSink sink = options.machineFormat ? errorSink : outSink; | 212 StringSink sink = options.machineFormat ? errorSink : outSink; |
| 212 sink.write(buffer); | 213 sink.write(buffer); |
| 213 } else { | 214 } else { |
| 214 new io.File(outputPath).writeAsStringSync(buffer.toString()); | 215 new io.File(outputPath).writeAsStringSync(buffer.toString()); |
| 215 } | 216 } |
| 216 } | 217 } |
| 217 | 218 |
| 218 /** | 219 /** |
| 219 * Serialize the library with the given [source] into [assembler] using only | 220 * Serialize the package with the given [sources] into [assembler] using only |
| 220 * its AST, [UnlinkedUnit]s of input packages and ASTs (via [UnlinkedUnit]s) | 221 * their ASTs and [LinkedUnit]s of input packages. |
| 221 * of package sources. | |
| 222 */ | 222 */ |
| 223 void _serializeAstBasedSummary(Source source) { | 223 void _serializeAstBasedSummary(List<Source> sources) { |
| 224 Source resolveRelativeUri(String relativeUri) { | 224 Set<String> sourceUris = |
| 225 Source resolvedSource = | 225 sources.map((Source s) => s.uri.toString()).toSet(); |
| 226 context.sourceFactory.resolveUri(source, relativeUri); | |
| 227 if (resolvedSource == null) { | |
| 228 context.sourceFactory.resolveUri(source, relativeUri); | |
| 229 throw new StateError('Could not resolve $relativeUri in the context of ' | |
| 230 '$source (${source.runtimeType})'); | |
| 231 } | |
| 232 return resolvedSource; | |
| 233 } | |
| 234 | 226 |
| 235 UnlinkedUnit _getUnlinkedUnit(Source source) { | 227 LinkedLibrary _getDependency(String absoluteUri) => |
| 228 summaryDataStore.linkedMap[absoluteUri]; |
| 229 |
| 230 UnlinkedUnit _getUnit(String absoluteUri) { |
| 236 // Maybe an input package contains the source. | 231 // Maybe an input package contains the source. |
| 237 { | 232 { |
| 238 String uriStr = source.uri.toString(); | 233 UnlinkedUnit unlinkedUnit = summaryDataStore.unlinkedMap[absoluteUri]; |
| 239 UnlinkedUnit unlinkedUnit = summaryDataStore.unlinkedMap[uriStr]; | |
| 240 if (unlinkedUnit != null) { | 234 if (unlinkedUnit != null) { |
| 241 return unlinkedUnit; | 235 return unlinkedUnit; |
| 242 } | 236 } |
| 243 } | 237 } |
| 244 // Parse the source and serialize its AST. | 238 // Parse the source and serialize its AST. |
| 245 return uriToUnit.putIfAbsent(source.uri, () { | 239 Uri uri = Uri.parse(absoluteUri); |
| 240 Source source = context.sourceFactory.forUri2(uri); |
| 241 return uriToUnit.putIfAbsent(uri, () { |
| 246 CompilationUnit unit = context.computeResult(source, PARSED_UNIT); | 242 CompilationUnit unit = context.computeResult(source, PARSED_UNIT); |
| 247 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit); | 243 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit); |
| 248 assembler.addUnlinkedUnit(source, unlinkedUnit); | 244 assembler.addUnlinkedUnit(source, unlinkedUnit); |
| 249 return unlinkedUnit; | 245 return unlinkedUnit; |
| 250 }); | 246 }); |
| 251 } | 247 } |
| 252 | 248 |
| 253 UnlinkedUnit getPart(String relativeUri) { | 249 Map<String, LinkedLibraryBuilder> linkResult = |
| 254 return _getUnlinkedUnit(resolveRelativeUri(relativeUri)); | 250 link(sourceUris, _getDependency, _getUnit, options.strongMode); |
| 255 } | 251 linkResult.forEach(assembler.addLinkedLibrary); |
| 256 | |
| 257 UnlinkedPublicNamespace getImport(String relativeUri) { | |
| 258 return getPart(relativeUri).publicNamespace; | |
| 259 } | |
| 260 | |
| 261 UnlinkedUnitBuilder definingUnit = _getUnlinkedUnit(source); | |
| 262 LinkedLibraryBuilder linkedLibrary = | |
| 263 prelink(definingUnit, getPart, getImport); | |
| 264 assembler.addLinkedLibrary(source.uri.toString(), linkedLibrary); | |
| 265 } | 252 } |
| 266 | 253 |
| 267 /** | 254 /** |
| 268 * Convert [sourceEntities] (a list of file specifications of the form | 255 * Convert [sourceEntities] (a list of file specifications of the form |
| 269 * "$uri|$path") to a map from URI to path. If an error occurs, report the | 256 * "$uri|$path") to a map from URI to path. If an error occurs, report the |
| 270 * error and return null. | 257 * error and return null. |
| 271 */ | 258 */ |
| 272 static Map<Uri, JavaFile> _createUriToFileMap(List<String> sourceEntities) { | 259 static Map<Uri, JavaFile> _createUriToFileMap(List<String> sourceEntities) { |
| 273 Map<Uri, JavaFile> uriToFileMap = <Uri, JavaFile>{}; | 260 Map<Uri, JavaFile> uriToFileMap = <Uri, JavaFile>{}; |
| 274 for (String sourceFile in sourceEntities) { | 261 for (String sourceFile in sourceEntities) { |
| 275 int pipeIndex = sourceFile.indexOf('|'); | 262 int pipeIndex = sourceFile.indexOf('|'); |
| 276 if (pipeIndex == -1) { | 263 if (pipeIndex == -1) { |
| 277 // TODO(paulberry): add the ability to guess the URI from the path. | 264 // TODO(paulberry): add the ability to guess the URI from the path. |
| 278 errorSink.writeln( | 265 errorSink.writeln( |
| 279 'Illegal input file (must be "\$uri|\$path"): $sourceFile'); | 266 'Illegal input file (must be "\$uri|\$path"): $sourceFile'); |
| 280 return null; | 267 return null; |
| 281 } | 268 } |
| 282 Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex)); | 269 Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex)); |
| 283 String path = sourceFile.substring(pipeIndex + 1); | 270 String path = sourceFile.substring(pipeIndex + 1); |
| 284 uriToFileMap[uri] = new JavaFile(path); | 271 uriToFileMap[uri] = new JavaFile(path); |
| 285 } | 272 } |
| 286 return uriToFileMap; | 273 return uriToFileMap; |
| 287 } | 274 } |
| 288 } | 275 } |
| 289 | 276 |
| 290 /** | 277 /** |
| 278 * Default implementation of [WorkerConnection] that works with stdio. |
| 279 */ |
| 280 class StdWorkerConnection implements WorkerConnection { |
| 281 final MessageGrouper _messageGrouper; |
| 282 final io.Stdout _stdoutStream; |
| 283 |
| 284 StdWorkerConnection(io.Stdin stdinStream, this._stdoutStream) |
| 285 : _messageGrouper = new MessageGrouper(stdinStream); |
| 286 |
| 287 @override |
| 288 WorkRequest readRequest() { |
| 289 var buffer = _messageGrouper.next; |
| 290 if (buffer == null) return null; |
| 291 |
| 292 return new WorkRequest.fromBuffer(buffer); |
| 293 } |
| 294 |
| 295 @override |
| 296 void writeResponse(WorkResponse response) { |
| 297 var responseBuffer = response.writeToBuffer(); |
| 298 |
| 299 var writer = new CodedBufferWriter(); |
| 300 writer.writeInt32NoTag(responseBuffer.length); |
| 301 writer.writeRawBytes(responseBuffer); |
| 302 |
| 303 _stdoutStream.add(writer.toBuffer()); |
| 304 } |
| 305 } |
| 306 |
| 307 /** |
| 291 * Connection between a worker and input / output. | 308 * Connection between a worker and input / output. |
| 292 */ | 309 */ |
| 293 abstract class WorkerConnection { | 310 abstract class WorkerConnection { |
| 294 /** | 311 /** |
| 295 * Read a new [WorkRequest]. Returns [null] when there are no more requests. | 312 * Read a new [WorkRequest]. Returns [null] when there are no more requests. |
| 296 */ | 313 */ |
| 297 WorkRequest readRequest(); | 314 WorkRequest readRequest(); |
| 298 | 315 |
| 299 /** | 316 /** |
| 300 * Write the given [response] as bytes to the output. | 317 * Write the given [response] as bytes to the output. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 String msg = ''; | 405 String msg = ''; |
| 389 if (errorBuffer.isNotEmpty) { | 406 if (errorBuffer.isNotEmpty) { |
| 390 msg += errorBuffer.toString() + '\n'; | 407 msg += errorBuffer.toString() + '\n'; |
| 391 } | 408 } |
| 392 if (outBuffer.isNotEmpty) { | 409 if (outBuffer.isNotEmpty) { |
| 393 msg += outBuffer.toString() + '\n'; | 410 msg += outBuffer.toString() + '\n'; |
| 394 } | 411 } |
| 395 return msg; | 412 return msg; |
| 396 } | 413 } |
| 397 } | 414 } |
| 398 | |
| 399 /** | |
| 400 * Default implementation of [WorkerConnection] that works with stdio. | |
| 401 */ | |
| 402 class StdWorkerConnection implements WorkerConnection { | |
| 403 final MessageGrouper _messageGrouper; | |
| 404 final io.Stdout _stdoutStream; | |
| 405 | |
| 406 StdWorkerConnection(io.Stdin stdinStream, this._stdoutStream) | |
| 407 : _messageGrouper = new MessageGrouper(stdinStream); | |
| 408 | |
| 409 @override | |
| 410 WorkRequest readRequest() { | |
| 411 var buffer = _messageGrouper.next; | |
| 412 if (buffer == null) return null; | |
| 413 | |
| 414 return new WorkRequest.fromBuffer(buffer); | |
| 415 } | |
| 416 | |
| 417 @override | |
| 418 void writeResponse(WorkResponse response) { | |
| 419 var responseBuffer = response.writeToBuffer(); | |
| 420 | |
| 421 var writer = new CodedBufferWriter(); | |
| 422 writer.writeInt32NoTag(responseBuffer.length); | |
| 423 writer.writeRawBytes(responseBuffer); | |
| 424 | |
| 425 _stdoutStream.add(writer.toBuffer()); | |
| 426 } | |
| 427 } | |
| OLD | NEW |