| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library input.transformer.instrumentation; | |
| 6 | |
| 7 import 'dart:convert'; | |
| 8 | |
| 9 import 'package:analyzer/src/generated/java_engine.dart'; | |
| 10 import 'package:analyzer/instrumentation/instrumentation.dart'; | |
| 11 import 'package:logging/logging.dart'; | |
| 12 | |
| 13 import 'input_converter.dart'; | |
| 14 import 'operation.dart'; | |
| 15 | |
| 16 final int COLON = ':'.codeUnitAt(0); | |
| 17 | |
| 18 /** | |
| 19 * [InstrumentationInputConverter] converts an instrumentation stream | |
| 20 * into a series of operations to be sent to the analysis server. | |
| 21 */ | |
| 22 class InstrumentationInputConverter extends CommonInputConverter { | |
| 23 final Set<String> codesSeen = new Set<String>(); | |
| 24 | |
| 25 /** | |
| 26 * [readBuffer] holds the contents of the file being read from disk | |
| 27 * as recorded in the instrumentation log | |
| 28 * or `null` if not converting a "Read" entry. | |
| 29 */ | |
| 30 StringBuffer readBuffer = null; | |
| 31 | |
| 32 InstrumentationInputConverter( | |
| 33 String tmpSrcDirPath, Map<String, String> srcPathMap, | |
| 34 {int diagnosticPort}) | |
| 35 : super(tmpSrcDirPath, srcPathMap, diagnosticPort: diagnosticPort); | |
| 36 | |
| 37 @override | |
| 38 Operation convert(String line) { | |
| 39 List<String> fields; | |
| 40 try { | |
| 41 fields = _parseFields(line); | |
| 42 if (fields.length < 2) { | |
| 43 if (readBuffer != null) { | |
| 44 readBuffer.writeln(fields.length == 1 ? fields[0] : ''); | |
| 45 return null; | |
| 46 } | |
| 47 throw 'Failed to process line:\n$line'; | |
| 48 } | |
| 49 if (readBuffer != null) { | |
| 50 readBuffer = null; | |
| 51 } | |
| 52 } catch (e, s) { | |
| 53 throw new AnalysisException( | |
| 54 'Failed to parse line\n$line', new CaughtException(e, s)); | |
| 55 } | |
| 56 // int timeStamp = int.parse(fields[0], onError: (_) => -1); | |
| 57 String opCode = fields[1]; | |
| 58 if (opCode == InstrumentationService.TAG_NOTIFICATION) { | |
| 59 return convertNotification(decodeJson(line, fields[2])); | |
| 60 } else if (opCode == 'Read') { | |
| 61 // 1434096943209:Read:/some/file/path:1434095535000:<file content> | |
| 62 //String filePath = fields[2]; | |
| 63 readBuffer = new StringBuffer(fields.length > 4 ? fields[4] : ''); | |
| 64 return null; | |
| 65 } else if (opCode == InstrumentationService.TAG_REQUEST) { | |
| 66 return convertRequest(decodeJson(line, fields[2])); | |
| 67 } else if (opCode == InstrumentationService.TAG_RESPONSE) { | |
| 68 // 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}} | |
| 69 return convertResponse(decodeJson(line, fields[2])); | |
| 70 } else if (opCode == InstrumentationService.TAG_ANALYSIS_TASK) { | |
| 71 // 1434096943208:Task:/Users/ | |
| 72 return null; | |
| 73 } else if (opCode == InstrumentationService.TAG_LOG_ENTRY) { | |
| 74 // 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}} | |
| 75 return null; | |
| 76 } else if (opCode == InstrumentationService.TAG_PERFORMANCE) { | |
| 77 //1434096960092:Perf:analysis_full:16884:context_id=0 | |
| 78 return null; | |
| 79 } else if (opCode == InstrumentationService.TAG_SUBPROCESS_START) { | |
| 80 // 1434096938634:SPStart:0:/Users/da | |
| 81 return null; | |
| 82 } else if (opCode == InstrumentationService.TAG_SUBPROCESS_RESULT) { | |
| 83 // 1434096939068:SPResult:0:0:"{\"packages\"::{\"rpi_lidar\"::\"/Users | |
| 84 return null; | |
| 85 } else if (opCode == InstrumentationService.TAG_VERSION) { | |
| 86 // 1434096937358:Ver:1421765742287333878467:org.dartlang.dartplugin | |
| 87 return null; | |
| 88 } else if (opCode == InstrumentationService.TAG_WATCH_EVENT) { | |
| 89 // 1434097460414:Watch:/some/file/path | |
| 90 return null; | |
| 91 } | |
| 92 if (codesSeen.add(opCode)) { | |
| 93 logger.log( | |
| 94 Level.WARNING, 'Ignored instrumentation op code: $opCode\n $line'); | |
| 95 } | |
| 96 return null; | |
| 97 } | |
| 98 | |
| 99 Map<String, dynamic> decodeJson(String line, String text) { | |
| 100 try { | |
| 101 return JSON.decode(text); | |
| 102 } catch (e, s) { | |
| 103 throw new AnalysisException( | |
| 104 'Failed to decode JSON: $text\n$line', new CaughtException(e, s)); | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 /** | |
| 109 * Determine if the given line is from an instrumentation file. | |
| 110 * For example: | |
| 111 * `1433175833005:Ver:1421765742287333878467:org.dartlang.dartplugin:0.0.0:1.6
.2:1.11.0-edge.131698` | |
| 112 */ | |
| 113 static bool isFormat(String line) { | |
| 114 List<String> fields = _parseFields(line); | |
| 115 if (fields.length < 2) return false; | |
| 116 int timeStamp = int.parse(fields[0], onError: (_) => -1); | |
| 117 String opCode = fields[1]; | |
| 118 return timeStamp > 0 && opCode == 'Ver'; | |
| 119 } | |
| 120 | |
| 121 /** | |
| 122 * Extract fields from the given [line]. | |
| 123 */ | |
| 124 static List<String> _parseFields(String line) { | |
| 125 List<String> fields = new List<String>(); | |
| 126 int index = 0; | |
| 127 StringBuffer sb = new StringBuffer(); | |
| 128 while (index < line.length) { | |
| 129 int code = line.codeUnitAt(index); | |
| 130 if (code == COLON) { | |
| 131 // Embedded colons are doubled | |
| 132 int next = index + 1; | |
| 133 if (next < line.length && line.codeUnitAt(next) == COLON) { | |
| 134 sb.write(':'); | |
| 135 ++index; | |
| 136 } else { | |
| 137 fields.add(sb.toString()); | |
| 138 sb.clear(); | |
| 139 } | |
| 140 } else { | |
| 141 sb.writeCharCode(code); | |
| 142 } | |
| 143 ++index; | |
| 144 } | |
| 145 if (sb.isNotEmpty) { | |
| 146 fields.add(sb.toString()); | |
| 147 } | |
| 148 return fields; | |
| 149 } | |
| 150 } | |
| OLD | NEW |