1ad68b9b16
As per our earlier conversation, I looked for places where a local variable was introduced to overcome field promotion and has the same name as the field. Where possible I made them final; where not possible I changed the name. Change-Id: Iad3d2139693ca66f1eb22a3926c3b84a4115f13d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196552 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
128 lines
4.3 KiB
Dart
128 lines
4.3 KiB
Dart
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'package:analyzer/exception/exception.dart';
|
|
import 'package:analyzer/instrumentation/instrumentation.dart';
|
|
import 'package:logging/logging.dart';
|
|
|
|
import 'input_converter.dart';
|
|
import 'operation.dart';
|
|
|
|
final int COLON = ':'.codeUnitAt(0);
|
|
|
|
/// [InstrumentationInputConverter] converts an instrumentation stream
|
|
/// into a series of operations to be sent to the analysis server.
|
|
class InstrumentationInputConverter extends CommonInputConverter {
|
|
final Set<String> codesSeen = <String>{};
|
|
|
|
/// [readBuffer] holds the contents of the file being read from disk
|
|
/// as recorded in the instrumentation log
|
|
/// or `null` if not converting a "Read" entry.
|
|
StringBuffer? readBuffer;
|
|
|
|
InstrumentationInputConverter(String tmpSrcDirPath, PathMap srcPathMap)
|
|
: super(tmpSrcDirPath, srcPathMap);
|
|
|
|
@override
|
|
Operation? convert(String line) {
|
|
List<String> fields;
|
|
try {
|
|
fields = _parseFields(line);
|
|
if (fields.length < 2) {
|
|
final readBuffer = this.readBuffer;
|
|
if (readBuffer != null) {
|
|
readBuffer.writeln(fields.length == 1 ? fields[0] : '');
|
|
return null;
|
|
}
|
|
throw 'Failed to process line:\n$line';
|
|
}
|
|
if (readBuffer != null) {
|
|
readBuffer = null;
|
|
}
|
|
} catch (e, s) {
|
|
throw AnalysisException(
|
|
'Failed to parse line\n$line', CaughtException(e, s));
|
|
}
|
|
// int timeStamp = int.parse(fields[0], onError: (_) => -1);
|
|
var opCode = fields[1];
|
|
if (opCode == InstrumentationLogAdapter.TAG_NOTIFICATION) {
|
|
return convertNotification(decodeJson(line, fields[2]));
|
|
} else if (opCode == 'Read') {
|
|
// 1434096943209:Read:/some/file/path:1434095535000:<file content>
|
|
//String filePath = fields[2];
|
|
readBuffer = StringBuffer(fields.length > 4 ? fields[4] : '');
|
|
return null;
|
|
} else if (opCode == InstrumentationLogAdapter.TAG_REQUEST) {
|
|
return convertRequest(decodeJson(line, fields[2]));
|
|
} else if (opCode == InstrumentationLogAdapter.TAG_RESPONSE) {
|
|
// 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}}
|
|
return convertResponse(decodeJson(line, fields[2]));
|
|
} else if (opCode == InstrumentationLogAdapter.TAG_LOG_ENTRY) {
|
|
// 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}}
|
|
return null;
|
|
} else if (opCode == InstrumentationLogAdapter.TAG_VERSION) {
|
|
// 1434096937358:Ver:1421765742287333878467:org.dartlang.dartplugin
|
|
return null;
|
|
} else if (opCode == InstrumentationLogAdapter.TAG_WATCH_EVENT) {
|
|
// 1434097460414:Watch:/some/file/path
|
|
return null;
|
|
}
|
|
if (codesSeen.add(opCode)) {
|
|
logger.log(
|
|
Level.WARNING, 'Ignored instrumentation op code: $opCode\n $line');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Map<String, Object?> decodeJson(String line, String text) {
|
|
try {
|
|
return asMap(json.decode(text));
|
|
} catch (e, s) {
|
|
throw AnalysisException(
|
|
'Failed to decode JSON: $text\n$line', CaughtException(e, s));
|
|
}
|
|
}
|
|
|
|
/// Determine if the given line is from an instrumentation file.
|
|
/// For example:
|
|
/// `1433175833005:Ver:1421765742287333878467:org.dartlang.dartplugin:0.0.0:1.6.2:1.11.0-edge.131698`
|
|
static bool isFormat(String line) {
|
|
var fields = _parseFields(line);
|
|
if (fields.length < 2) return false;
|
|
var timeStamp = int.tryParse(fields[0]) ?? -1;
|
|
var opCode = fields[1];
|
|
return timeStamp > 0 && opCode == 'Ver';
|
|
}
|
|
|
|
/// Extract fields from the given [line].
|
|
static List<String> _parseFields(String line) {
|
|
var fields = <String>[];
|
|
var index = 0;
|
|
var sb = StringBuffer();
|
|
while (index < line.length) {
|
|
var code = line.codeUnitAt(index);
|
|
if (code == COLON) {
|
|
// Embedded colons are doubled
|
|
var next = index + 1;
|
|
if (next < line.length && line.codeUnitAt(next) == COLON) {
|
|
sb.write(':');
|
|
++index;
|
|
} else {
|
|
fields.add(sb.toString());
|
|
sb.clear();
|
|
}
|
|
} else {
|
|
sb.writeCharCode(code);
|
|
}
|
|
++index;
|
|
}
|
|
if (sb.isNotEmpty) {
|
|
fields.add(sb.toString());
|
|
}
|
|
return fields;
|
|
}
|
|
}
|