| 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:analyzer/dart/ast/ast.dart' show CompilationUnit; | 10 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 import 'package:analyzer/src/summary/idl.dart'; | 21 import 'package:analyzer/src/summary/idl.dart'; |
| 22 import 'package:analyzer/src/summary/link.dart'; | 22 import 'package:analyzer/src/summary/link.dart'; |
| 23 import 'package:analyzer/src/summary/package_bundle_reader.dart'; | 23 import 'package:analyzer/src/summary/package_bundle_reader.dart'; |
| 24 import 'package:analyzer/src/summary/summarize_ast.dart'; | 24 import 'package:analyzer/src/summary/summarize_ast.dart'; |
| 25 import 'package:analyzer/src/summary/summarize_elements.dart'; | 25 import 'package:analyzer/src/summary/summarize_elements.dart'; |
| 26 import 'package:analyzer/task/dart.dart'; | 26 import 'package:analyzer/task/dart.dart'; |
| 27 import 'package:analyzer_cli/src/analyzer_impl.dart'; | 27 import 'package:analyzer_cli/src/analyzer_impl.dart'; |
| 28 import 'package:analyzer_cli/src/driver.dart'; | 28 import 'package:analyzer_cli/src/driver.dart'; |
| 29 import 'package:analyzer_cli/src/error_formatter.dart'; | 29 import 'package:analyzer_cli/src/error_formatter.dart'; |
| 30 import 'package:analyzer_cli/src/options.dart'; | 30 import 'package:analyzer_cli/src/options.dart'; |
| 31 import 'package:protobuf/protobuf.dart'; | 31 import 'package:bazel_worker/bazel_worker.dart'; |
| 32 | |
| 33 import 'message_grouper.dart'; | |
| 34 import 'worker_protocol.pb.dart'; | |
| 35 | 32 |
| 36 /** | 33 /** |
| 37 * Analyzer used when the "--build-mode" option is supplied. | 34 * Analyzer used when the "--build-mode" option is supplied. |
| 38 */ | 35 */ |
| 39 class BuildMode { | 36 class BuildMode { |
| 40 final CommandLineOptions options; | 37 final CommandLineOptions options; |
| 41 final AnalysisStats stats; | 38 final AnalysisStats stats; |
| 42 | 39 |
| 43 final ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE; | 40 final ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE; |
| 44 SummaryDataStore summaryDataStore; | 41 SummaryDataStore summaryDataStore; |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 } | 265 } |
| 269 Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex)); | 266 Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex)); |
| 270 String path = sourceFile.substring(pipeIndex + 1); | 267 String path = sourceFile.substring(pipeIndex + 1); |
| 271 uriToFileMap[uri] = new JavaFile(path); | 268 uriToFileMap[uri] = new JavaFile(path); |
| 272 } | 269 } |
| 273 return uriToFileMap; | 270 return uriToFileMap; |
| 274 } | 271 } |
| 275 } | 272 } |
| 276 | 273 |
| 277 /** | 274 /** |
| 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 /** | |
| 308 * Connection between a worker and input / output. | |
| 309 */ | |
| 310 abstract class WorkerConnection { | |
| 311 /** | |
| 312 * Read a new [WorkRequest]. Returns [null] when there are no more requests. | |
| 313 */ | |
| 314 WorkRequest readRequest(); | |
| 315 | |
| 316 /** | |
| 317 * Write the given [response] as bytes to the output. | |
| 318 */ | |
| 319 void writeResponse(WorkResponse response); | |
| 320 } | |
| 321 | |
| 322 /** | |
| 323 * Persistent Bazel worker. | 275 * Persistent Bazel worker. |
| 324 */ | 276 */ |
| 325 class WorkerLoop { | 277 class AnalyzerWorkerLoop extends SyncWorkerLoop { |
| 326 static const int EXIT_CODE_OK = 0; | |
| 327 static const int EXIT_CODE_ERROR = 15; | |
| 328 | |
| 329 final WorkerConnection connection; | |
| 330 | |
| 331 final StringBuffer errorBuffer = new StringBuffer(); | 278 final StringBuffer errorBuffer = new StringBuffer(); |
| 332 final StringBuffer outBuffer = new StringBuffer(); | 279 final StringBuffer outBuffer = new StringBuffer(); |
| 333 | 280 |
| 334 final String dartSdkPath; | 281 final String dartSdkPath; |
| 335 | 282 |
| 336 WorkerLoop(this.connection, {this.dartSdkPath}); | 283 AnalyzerWorkerLoop(SyncWorkerConnection connection, {this.dartSdkPath}) |
| 284 : super(connection: connection); |
| 337 | 285 |
| 338 factory WorkerLoop.std( | 286 factory AnalyzerWorkerLoop.std( |
| 339 {io.Stdin stdinStream, io.Stdout stdoutStream, String dartSdkPath}) { | 287 {io.Stdin stdinStream, io.Stdout stdoutStream, String dartSdkPath}) { |
| 340 stdinStream ??= io.stdin; | 288 SyncWorkerConnection connection = new StdSyncWorkerConnection( |
| 341 stdoutStream ??= io.stdout; | 289 stdinStream: stdinStream, stdoutStream: stdoutStream); |
| 342 WorkerConnection connection = | 290 return new AnalyzerWorkerLoop(connection, dartSdkPath: dartSdkPath); |
| 343 new StdWorkerConnection(stdinStream, stdoutStream); | |
| 344 return new WorkerLoop(connection, dartSdkPath: dartSdkPath); | |
| 345 } | 291 } |
| 346 | 292 |
| 347 /** | 293 /** |
| 348 * Performs analysis with given [options]. | 294 * Performs analysis with given [options]. |
| 349 */ | 295 */ |
| 350 void analyze(CommandLineOptions options) { | 296 void analyze(CommandLineOptions options) { |
| 351 options.dartSdkPath ??= dartSdkPath; | 297 options.dartSdkPath ??= dartSdkPath; |
| 352 new BuildMode(options, new AnalysisStats()).analyze(); | 298 new BuildMode(options, new AnalysisStats()).analyze(); |
| 353 } | 299 } |
| 354 | 300 |
| 355 /** | 301 /** |
| 356 * Perform a single loop step. Return `true` if should exit the loop. | 302 * Perform a single loop step. |
| 357 */ | 303 */ |
| 358 bool performSingle() { | 304 WorkResponse performRequest(WorkRequest request) { |
| 305 errorBuffer.clear(); |
| 306 outBuffer.clear(); |
| 359 try { | 307 try { |
| 360 WorkRequest request = connection.readRequest(); | |
| 361 if (request == null) { | |
| 362 return true; | |
| 363 } | |
| 364 // Prepare options. | 308 // Prepare options. |
| 365 CommandLineOptions options = | 309 CommandLineOptions options = |
| 366 CommandLineOptions.parse(request.arguments, (String msg) { | 310 CommandLineOptions.parse(request.arguments, (String msg) { |
| 367 throw new ArgumentError(msg); | 311 throw new ArgumentError(msg); |
| 368 }); | 312 }); |
| 369 // Analyze and respond. | 313 // Analyze and respond. |
| 370 analyze(options); | 314 analyze(options); |
| 371 String msg = _getErrorOutputBuffersText(); | 315 String msg = _getErrorOutputBuffersText(); |
| 372 connection.writeResponse(new WorkResponse() | 316 return new WorkResponse() |
| 373 ..exitCode = EXIT_CODE_OK | 317 ..exitCode = EXIT_CODE_OK |
| 374 ..output = msg); | 318 ..output = msg; |
| 375 } catch (e, st) { | 319 } catch (e, st) { |
| 376 String msg = _getErrorOutputBuffersText(); | 320 String msg = _getErrorOutputBuffersText(); |
| 377 msg += '$e \n $st'; | 321 msg += '$e\n$st'; |
| 378 connection.writeResponse(new WorkResponse() | 322 return new WorkResponse() |
| 379 ..exitCode = EXIT_CODE_ERROR | 323 ..exitCode = EXIT_CODE_ERROR |
| 380 ..output = msg); | 324 ..output = msg; |
| 381 } | 325 } |
| 382 return false; | |
| 383 } | 326 } |
| 384 | 327 |
| 385 /** | 328 /** |
| 386 * Run the worker loop. | 329 * Run the worker loop. |
| 387 */ | 330 */ |
| 331 @override |
| 388 void run() { | 332 void run() { |
| 389 errorSink = errorBuffer; | 333 errorSink = errorBuffer; |
| 390 outSink = outBuffer; | 334 outSink = outBuffer; |
| 391 exitHandler = (int exitCode) { | 335 exitHandler = (int exitCode) { |
| 392 return throw new StateError('Exit called: $exitCode'); | 336 return throw new StateError('Exit called: $exitCode'); |
| 393 }; | 337 }; |
| 394 while (true) { | 338 super.run(); |
| 395 errorBuffer.clear(); | |
| 396 outBuffer.clear(); | |
| 397 bool shouldExit = performSingle(); | |
| 398 if (shouldExit) { | |
| 399 break; | |
| 400 } | |
| 401 } | |
| 402 } | 339 } |
| 403 | 340 |
| 404 String _getErrorOutputBuffersText() { | 341 String _getErrorOutputBuffersText() { |
| 405 String msg = ''; | 342 String msg = ''; |
| 406 if (errorBuffer.isNotEmpty) { | 343 if (errorBuffer.isNotEmpty) { |
| 407 msg += errorBuffer.toString() + '\n'; | 344 msg += errorBuffer.toString() + '\n'; |
| 408 } | 345 } |
| 409 if (outBuffer.isNotEmpty) { | 346 if (outBuffer.isNotEmpty) { |
| 410 msg += outBuffer.toString() + '\n'; | 347 msg += outBuffer.toString() + '\n'; |
| 411 } | 348 } |
| 412 return msg; | 349 return msg; |
| 413 } | 350 } |
| 414 } | 351 } |
| OLD | NEW |