| 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 input.transformer; | 5 library input.transformer; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 | 10 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 /** | 55 /** |
| 56 * The prefix used to determine if a request parameter is a file path. | 56 * The prefix used to determine if a request parameter is a file path. |
| 57 */ | 57 */ |
| 58 final String rootPrefix = path.rootPrefix(path.current); | 58 final String rootPrefix = path.rootPrefix(path.current); |
| 59 | 59 |
| 60 /** | 60 /** |
| 61 * A mapping of source path prefixes | 61 * A mapping of source path prefixes |
| 62 * from location where instrumentation or log file was generated | 62 * from location where instrumentation or log file was generated |
| 63 * to the target location of the source using during performance measurement. | 63 * to the target location of the source using during performance measurement. |
| 64 */ | 64 */ |
| 65 final Map<String, String> srcPathMap; | 65 final PathMap srcPathMap; |
| 66 | 66 |
| 67 /** | 67 /** |
| 68 * The root directory for all source being modified | 68 * The root directory for all source being modified |
| 69 * during performance measurement. | 69 * during performance measurement. |
| 70 */ | 70 */ |
| 71 final String tmpSrcDirPath; | 71 final String tmpSrcDirPath; |
| 72 | 72 |
| 73 /** | 73 CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap); |
| 74 * The diagnostic port for Analysis Server or `null` if none. | |
| 75 */ | |
| 76 final int diagnosticPort; | |
| 77 | |
| 78 CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap, | |
| 79 {this.diagnosticPort}); | |
| 80 | 74 |
| 81 /** | 75 /** |
| 82 * Return an operation for the notification or `null` if none. | 76 * Return an operation for the notification or `null` if none. |
| 83 */ | 77 */ |
| 84 Operation convertNotification(Map<String, dynamic> json) { | 78 Operation convertNotification(Map<String, dynamic> json) { |
| 85 String event = json['event']; | 79 String event = json['event']; |
| 86 if (event == SERVER_STATUS) { | 80 if (event == SERVER_STATUS) { |
| 87 // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}} | 81 // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}} |
| 88 Map<String, dynamic> params = json['params']; | 82 Map<String, dynamic> params = json['params']; |
| 89 if (params != null) { | 83 if (params != null) { |
| 90 Map<String, dynamic> analysis = params['analysis']; | 84 Map<String, dynamic> analysis = params['analysis']; |
| 91 if (analysis != null && analysis['isAnalyzing'] == false) { | 85 if (analysis != null && analysis['isAnalyzing'] == false) { |
| 92 return new WaitForAnalysisCompleteOperation(); | 86 return new WaitForAnalysisCompleteOperation(); |
| 93 } | 87 } |
| 94 } | 88 } |
| 95 } | 89 } |
| 96 if (event == SERVER_CONNECTED) { | 90 if (event == SERVER_CONNECTED) { |
| 97 // {"event":"server.connected","params":{"version":"1.7.0"}} | 91 // {"event":"server.connected","params":{"version":"1.7.0"}} |
| 98 return new StartServerOperation(diagnosticPort: diagnosticPort); | 92 return new StartServerOperation(); |
| 99 } | 93 } |
| 100 if (eventsSeen.add(event)) { | 94 if (eventsSeen.add(event)) { |
| 101 logger.log(Level.INFO, 'Ignored notification: $event\n $json'); | 95 logger.log(Level.INFO, 'Ignored notification: $event\n $json'); |
| 102 } | 96 } |
| 103 return null; | 97 return null; |
| 104 } | 98 } |
| 105 | 99 |
| 106 /** | 100 /** |
| 107 * Return an operation for the request or `null` if none. | 101 * Return an operation for the request or `null` if none. |
| 108 */ | 102 */ |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 169 } |
| 176 | 170 |
| 177 /** | 171 /** |
| 178 * Return an operation for the recorded/expected response. | 172 * Return an operation for the recorded/expected response. |
| 179 */ | 173 */ |
| 180 Operation convertResponse(Map<String, dynamic> json) { | 174 Operation convertResponse(Map<String, dynamic> json) { |
| 181 return new ResponseOperation( | 175 return new ResponseOperation( |
| 182 this, requestMap.remove(json['id']), translateSrcPaths(json)); | 176 this, requestMap.remove(json['id']), translateSrcPaths(json)); |
| 183 } | 177 } |
| 184 | 178 |
| 179 void logOverlayContent() { |
| 180 logger.log(Level.WARNING, '${overlays.length} overlays'); |
| 181 List<String> allPaths = overlays.keys.toList()..sort(); |
| 182 for (String filePath in allPaths) { |
| 183 logger.log(Level.WARNING, 'overlay $filePath\n${overlays[filePath]}'); |
| 184 } |
| 185 } |
| 186 |
| 185 /** | 187 /** |
| 186 * Process an error response from the server by either | 188 * Process an error response from the server by either |
| 187 * completing the associated completer in the [responseCompleters] | 189 * completing the associated completer in the [responseCompleters] |
| 188 * or stashing it in [responseMap] if no completer exists. | 190 * or stashing it in [responseMap] if no completer exists. |
| 189 */ | 191 */ |
| 190 void processErrorResponse(String id, exception) { | 192 void processErrorResponse(String id, exception) { |
| 191 var result = exception; | 193 var result = exception; |
| 192 if (exception is UnimplementedError) { | 194 if (exception is UnimplementedError) { |
| 193 if (exception.message.startsWith(ERROR_PREFIX)) { | 195 if (exception.message.startsWith(ERROR_PREFIX)) { |
| 194 result = JSON.decode(exception.message.substring(ERROR_PREFIX.length)); | 196 result = JSON.decode(exception.message.substring(ERROR_PREFIX.length)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 } | 237 } |
| 236 } | 238 } |
| 237 | 239 |
| 238 /** | 240 /** |
| 239 * Recursively translate source paths in the specified JSON to reference | 241 * Recursively translate source paths in the specified JSON to reference |
| 240 * the temporary source used during performance measurement rather than | 242 * the temporary source used during performance measurement rather than |
| 241 * the original source when the instrumentation or log file was generated. | 243 * the original source when the instrumentation or log file was generated. |
| 242 */ | 244 */ |
| 243 translateSrcPaths(json) { | 245 translateSrcPaths(json) { |
| 244 if (json is String) { | 246 if (json is String) { |
| 245 String result = json; | 247 return srcPathMap.translate(json); |
| 246 srcPathMap.forEach((String oldPrefix, String newPrefix) { | |
| 247 if (json.startsWith(oldPrefix)) { | |
| 248 result = '$newPrefix${json.substring(oldPrefix.length)}'; | |
| 249 } | |
| 250 }); | |
| 251 return result; | |
| 252 } | 248 } |
| 253 if (json is List) { | 249 if (json is List) { |
| 254 List result = []; | 250 List result = []; |
| 255 for (int i = 0; i < json.length; ++i) { | 251 for (int i = 0; i < json.length; ++i) { |
| 256 result.add(translateSrcPaths(json[i])); | 252 result.add(translateSrcPaths(json[i])); |
| 257 } | 253 } |
| 258 return result; | 254 return result; |
| 259 } | 255 } |
| 260 if (json is Map) { | 256 if (json is Map) { |
| 261 Map<String, dynamic> result = new Map<String, dynamic>(); | 257 Map<String, dynamic> result = new Map<String, dynamic>(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 274 * The input stream can be either an instrumenation or log file. | 270 * The input stream can be either an instrumenation or log file. |
| 275 */ | 271 */ |
| 276 class InputConverter extends Converter<String, Operation> { | 272 class InputConverter extends Converter<String, Operation> { |
| 277 final Logger logger = new Logger('InputConverter'); | 273 final Logger logger = new Logger('InputConverter'); |
| 278 | 274 |
| 279 /** | 275 /** |
| 280 * A mapping of source path prefixes | 276 * A mapping of source path prefixes |
| 281 * from location where instrumentation or log file was generated | 277 * from location where instrumentation or log file was generated |
| 282 * to the target location of the source using during performance measurement. | 278 * to the target location of the source using during performance measurement. |
| 283 */ | 279 */ |
| 284 final Map<String, String> srcPathMap; | 280 final PathMap srcPathMap; |
| 285 | 281 |
| 286 /** | 282 /** |
| 287 * The root directory for all source being modified | 283 * The root directory for all source being modified |
| 288 * during performance measurement. | 284 * during performance measurement. |
| 289 */ | 285 */ |
| 290 final String tmpSrcDirPath; | 286 final String tmpSrcDirPath; |
| 291 | 287 |
| 292 /** | 288 /** |
| 293 * The diagnostic port for Analysis Server or `null` if none. | |
| 294 */ | |
| 295 final int diagnosticPort; | |
| 296 | |
| 297 /** | |
| 298 * The number of lines read before the underlying converter was determined | 289 * The number of lines read before the underlying converter was determined |
| 299 * or the end of file was reached. | 290 * or the end of file was reached. |
| 300 */ | 291 */ |
| 301 int headerLineCount = 0; | 292 int headerLineCount = 0; |
| 302 | 293 |
| 303 /** | 294 /** |
| 304 * The underlying converter used to translate lines into operations | 295 * The underlying converter used to translate lines into operations |
| 305 * or `null` if it has not yet been determined. | 296 * or `null` if it has not yet been determined. |
| 306 */ | 297 */ |
| 307 Converter<String, Operation> converter; | 298 Converter<String, Operation> converter; |
| 308 | 299 |
| 309 /** | 300 /** |
| 310 * [active] is `true` if converting lines to operations | 301 * [active] is `true` if converting lines to operations |
| 311 * or `false` if an exception has occurred. | 302 * or `false` if an exception has occurred. |
| 312 */ | 303 */ |
| 313 bool active = true; | 304 bool active = true; |
| 314 | 305 |
| 315 InputConverter(this.tmpSrcDirPath, this.srcPathMap, {this.diagnosticPort}); | 306 InputConverter(this.tmpSrcDirPath, this.srcPathMap); |
| 316 | 307 |
| 317 @override | 308 @override |
| 318 Operation convert(String line) { | 309 Operation convert(String line) { |
| 319 if (!active) { | 310 if (!active) { |
| 320 return null; | 311 return null; |
| 321 } | 312 } |
| 322 if (converter != null) { | 313 if (converter != null) { |
| 323 try { | 314 try { |
| 324 return converter.convert(line); | 315 return converter.convert(line); |
| 325 } catch (e) { | 316 } catch (e) { |
| 326 active = false; | 317 active = false; |
| 327 rethrow; | 318 rethrow; |
| 328 } | 319 } |
| 329 } | 320 } |
| 330 if (headerLineCount == 20) { | 321 if (headerLineCount == 20) { |
| 331 throw 'Failed to determine input file format'; | 322 throw 'Failed to determine input file format'; |
| 332 } | 323 } |
| 333 if (InstrumentationInputConverter.isFormat(line)) { | 324 if (InstrumentationInputConverter.isFormat(line)) { |
| 334 converter = new InstrumentationInputConverter(tmpSrcDirPath, srcPathMap, | 325 converter = new InstrumentationInputConverter(tmpSrcDirPath, srcPathMap); |
| 335 diagnosticPort: diagnosticPort); | |
| 336 } else if (LogFileInputConverter.isFormat(line)) { | 326 } else if (LogFileInputConverter.isFormat(line)) { |
| 337 converter = new LogFileInputConverter(tmpSrcDirPath, srcPathMap, | 327 converter = new LogFileInputConverter(tmpSrcDirPath, srcPathMap); |
| 338 diagnosticPort: diagnosticPort); | |
| 339 } | 328 } |
| 340 if (converter != null) { | 329 if (converter != null) { |
| 341 return converter.convert(line); | 330 return converter.convert(line); |
| 342 } | 331 } |
| 343 logger.log(Level.INFO, 'skipped input line: $line'); | 332 logger.log(Level.INFO, 'skipped input line: $line'); |
| 344 return null; | 333 return null; |
| 345 } | 334 } |
| 346 | 335 |
| 347 @override | 336 @override |
| 348 _InputSink startChunkedConversion(outSink) { | 337 _InputSink startChunkedConversion(outSink) { |
| 349 return new _InputSink(this, outSink); | 338 return new _InputSink(this, outSink); |
| 350 } | 339 } |
| 351 } | 340 } |
| 352 | 341 |
| 342 /** |
| 343 * A container of [PathMapEntry]s used to translate a source path in the log |
| 344 * before it is sent to the analysis server. |
| 345 */ |
| 346 class PathMap { |
| 347 final List<PathMapEntry> entries = []; |
| 348 |
| 349 void add(String oldSrcPrefix, String newSrcPrefix) { |
| 350 entries.add(new PathMapEntry(oldSrcPrefix, newSrcPrefix)); |
| 351 } |
| 352 |
| 353 String translate(String original) { |
| 354 String result = original; |
| 355 for (PathMapEntry entry in entries) { |
| 356 result = entry.translate(result); |
| 357 } |
| 358 return result; |
| 359 } |
| 360 } |
| 361 |
| 362 /** |
| 363 * An entry in [PathMap] used to translate a source path in the log |
| 364 * before it is sent to the analysis server. |
| 365 */ |
| 366 class PathMapEntry { |
| 367 final String oldSrcPrefix; |
| 368 final String newSrcPrefix; |
| 369 |
| 370 PathMapEntry(this.oldSrcPrefix, this.newSrcPrefix); |
| 371 |
| 372 String translate(String original) { |
| 373 return original.startsWith(oldSrcPrefix) |
| 374 ? '$newSrcPrefix${original.substring(oldSrcPrefix.length)}' |
| 375 : original; |
| 376 } |
| 377 } |
| 378 |
| 353 class _InputSink extends ChunkedConversionSink<String> { | 379 class _InputSink extends ChunkedConversionSink<String> { |
| 354 final Converter<String, Operation> converter; | 380 final Converter<String, Operation> converter; |
| 355 final outSink; | 381 final outSink; |
| 356 | 382 |
| 357 _InputSink(this.converter, this.outSink); | 383 _InputSink(this.converter, this.outSink); |
| 358 | 384 |
| 359 @override | 385 @override |
| 360 void add(String line) { | 386 void add(String line) { |
| 361 Operation op = converter.convert(line); | 387 Operation op = converter.convert(line); |
| 362 if (op != null) { | 388 if (op != null) { |
| 363 outSink.add(op); | 389 outSink.add(op); |
| 364 } | 390 } |
| 365 } | 391 } |
| 366 | 392 |
| 367 @override | 393 @override |
| 368 void close() { | 394 void close() { |
| 369 outSink.close(); | 395 outSink.close(); |
| 370 } | 396 } |
| 371 } | 397 } |
| OLD | NEW |