| OLD | NEW |
| (Empty) | |
| 1 library input.transformer.instrumentation; |
| 2 |
| 3 import 'dart:convert'; |
| 4 |
| 5 import 'package:logging/logging.dart'; |
| 6 |
| 7 import 'operation.dart'; |
| 8 |
| 9 final int COLON = ':'.codeUnitAt(0); |
| 10 |
| 11 /** |
| 12 * [InstrumentationInputConverter] converts an instrumentation stream |
| 13 * into a series of operations to be sent to the analysis server. |
| 14 */ |
| 15 class InstrumentationInputConverter extends Converter<String, Operation> { |
| 16 final Logger logger = new Logger('InstrumentationInputConverter'); |
| 17 final Set<String> _codesSeen = new Set<String>(); |
| 18 final Set<String> _methodsSeen = new Set<String>(); |
| 19 final Set<String> _eventsSeen = new Set<String>(); |
| 20 |
| 21 @override |
| 22 Operation convert(String line) { |
| 23 try { |
| 24 List<String> fields = _parseFields(line); |
| 25 if (fields.length < 2) { |
| 26 //return new InfoOperation('Ignored line:\n $line'); |
| 27 return null; |
| 28 } |
| 29 // int timeStamp = int.parse(fields[0], onError: (_) => -1); |
| 30 String opCode = fields[1]; |
| 31 if (opCode == 'Req') { |
| 32 return convertRequest(line, fields); |
| 33 } |
| 34 if (opCode == 'Noti') { |
| 35 return convertNotification(fields); |
| 36 } |
| 37 if (opCode == 'Ver') { |
| 38 // 1433195174666:Ver:1421765742287333878467:org.dartlang.dartplugin:0.0.
0:1.7.0:1.11.0-edge.131698 |
| 39 return new StartServerOperation(); |
| 40 } |
| 41 if (_codesSeen.add(opCode)) { |
| 42 logger.log(Level.INFO, 'Ignored op code: $opCode\n $line'); |
| 43 } |
| 44 return null; |
| 45 } catch (e, s) { |
| 46 throw 'Failed to parse line\n $line\n$e\n$s'; |
| 47 } |
| 48 } |
| 49 |
| 50 /** |
| 51 * Return an operation for the notification defined by [line] and [fields] |
| 52 * or `null` if none. |
| 53 */ |
| 54 Operation convertNotification(List<String> fields) { |
| 55 //1433344448533:Noti:{"event"::"server.status","params"::{"analysis"::{"isAn
alyzing"::false}}} |
| 56 Map<String, dynamic> json = JSON.decode(fields[2]); |
| 57 String event = json['event']; |
| 58 if (event == 'server.status') { |
| 59 Map<String, dynamic> params = json['params']; |
| 60 if (params != null) { |
| 61 Map<String, dynamic> analysis = params['analysis']; |
| 62 if (analysis != null && analysis['isAnalyzing'] == false) { |
| 63 return new WaitForAnalysisCompleteOperation(); |
| 64 } |
| 65 } |
| 66 } |
| 67 if (event == 'server.connected') { |
| 68 // Handled by the driver |
| 69 return null; |
| 70 } |
| 71 if (_eventsSeen.add(event)) { |
| 72 logger.log(Level.INFO, 'Ignored notification: $event'); |
| 73 } |
| 74 return null; |
| 75 } |
| 76 |
| 77 /** |
| 78 * Return an operation for the request defined by [line] and [fields] |
| 79 * or `null` if none. |
| 80 */ |
| 81 Operation convertRequest(String line, List<String> fields) { |
| 82 Map<String, dynamic> json = JSON.decode(fields[2]); |
| 83 String method = json['method']; |
| 84 if (method == 'analysis.setAnalysisRoots') { |
| 85 // 1433343174749:Req:{"id"::"3","method"::"analysis.setAnalysisRoots","par
ams"::{"included"::["/usr/local/google/home/danrubel/work/git/dart_sdk/sdk/pkg/a
nalysis_server","/usr/local/google/home/danrubel/work/git/dart_sdk/sdk/pkg/analy
zer"],"excluded"::[],"packageRoots"::{}},"clientRequestTime"::1433343174702} |
| 86 return new RequestOperation(json); |
| 87 } |
| 88 if (method == 'server.setSubscriptions') { |
| 89 // 1433343174741:Req:{"id"::"1","method"::"server.setSubscriptions","param
s"::{"subscriptions"::["STATUS"]},"clientRequestTime"::1433343172679} |
| 90 return new RequestOperation(json); |
| 91 } |
| 92 if (_methodsSeen.add(method)) { |
| 93 logger.log(Level.INFO, 'Ignored request: $method\n $line'); |
| 94 } |
| 95 return null; |
| 96 } |
| 97 |
| 98 /** |
| 99 * Determine if the given line is from an instrumentation file. |
| 100 * For example: |
| 101 * `1433175833005:Ver:1421765742287333878467:org.dartlang.dartplugin:0.0.0:1.6
.2:1.11.0-edge.131698` |
| 102 */ |
| 103 static bool isFormat(String line) { |
| 104 List<String> fields = _parseFields(line); |
| 105 int timeStamp = int.parse(fields[0], onError: (_) => -1); |
| 106 String opCode = fields[1]; |
| 107 return timeStamp > 0 && opCode == 'Ver'; |
| 108 } |
| 109 |
| 110 /** |
| 111 * Extract fields from the given [line]. |
| 112 */ |
| 113 static List<String> _parseFields(String line) { |
| 114 List<String> fields = new List<String>(); |
| 115 int index = 0; |
| 116 StringBuffer sb = new StringBuffer(); |
| 117 while (index < line.length) { |
| 118 int code = line.codeUnitAt(index); |
| 119 if (code == COLON) { |
| 120 // Embedded colons are doubled |
| 121 int next = index + 1; |
| 122 if (next < line.length && line.codeUnitAt(next) == COLON) { |
| 123 sb.write(':'); |
| 124 ++index; |
| 125 } else { |
| 126 fields.add(sb.toString()); |
| 127 sb.clear(); |
| 128 } |
| 129 } else { |
| 130 sb.writeCharCode(code); |
| 131 } |
| 132 ++index; |
| 133 } |
| 134 if (sb.isNotEmpty) { |
| 135 fields.add(sb.toString()); |
| 136 } |
| 137 return fields; |
| 138 } |
| 139 } |
| OLD | NEW |