Unverified Commit 6a390aa7 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] fix type error in symbolize (#55212)

parent 9e72bf56
...@@ -113,9 +113,46 @@ class SymbolizeCommand extends FlutterCommand { ...@@ -113,9 +113,46 @@ class SymbolizeCommand extends FlutterCommand {
} }
} }
typedef SymbolsTransformer = StreamTransformer<String, String> Function(Uint8List);
StreamTransformer<String, String> _defaultTransformer(Uint8List symbols) {
final Dwarf dwarf = Dwarf.fromBytes(symbols);
if (dwarf == null) {
throwToolExit('Failed to decode symbols file');
}
return DwarfStackTraceDecoder(dwarf, includeInternalFrames: true);
}
// A no-op transformer for `DwarfSymbolizationService.test`
StreamTransformer<String, String> _testTransformer(Uint8List buffer) {
return StreamTransformer<String, String>.fromHandlers(
handleData: (String data, EventSink<String> sink) {
sink.add(data);
},
handleDone: (EventSink<String> sink) {
sink.close();
},
handleError: (dynamic error, StackTrace stackTrace, EventSink<String> sink) {
sink.addError(error, stackTrace);
}
);
}
/// A service which decodes stack traces from Dart applications. /// A service which decodes stack traces from Dart applications.
class DwarfSymbolizationService { class DwarfSymbolizationService {
const DwarfSymbolizationService(); const DwarfSymbolizationService({
SymbolsTransformer symbolsTransformer = _defaultTransformer,
}) : _transformer = symbolsTransformer;
/// Create a DwarfSymbolizationService with a no-op transformer for testing.
@visibleForTesting
factory DwarfSymbolizationService.test() {
return const DwarfSymbolizationService(
symbolsTransformer: _testTransformer
);
}
final SymbolsTransformer _transformer;
/// Decode a stack trace from [input] and place the results in [output]. /// Decode a stack trace from [input] and place the results in [output].
/// ///
...@@ -129,17 +166,13 @@ class DwarfSymbolizationService { ...@@ -129,17 +166,13 @@ class DwarfSymbolizationService {
@required IOSink output, @required IOSink output,
@required Uint8List symbols, @required Uint8List symbols,
}) async { }) async {
final Dwarf dwarf = Dwarf.fromBytes(symbols);
if (dwarf == null) {
throwToolExit('Failed to decode symbols file');
}
final Completer<void> onDone = Completer<void>(); final Completer<void> onDone = Completer<void>();
StreamSubscription<void> subscription; StreamSubscription<void> subscription;
subscription = input subscription = input
.cast<List<int>>()
.transform(const Utf8Decoder()) .transform(const Utf8Decoder())
.transform(const LineSplitter()) .transform(const LineSplitter())
.transform(DwarfStackTraceDecoder(dwarf, includeInternalFrames: true)) .transform(_transformer(symbols))
.listen((String line) { .listen((String line) {
try { try {
output.writeln(line); output.writeln(line);
......
...@@ -2,10 +2,12 @@ ...@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/symbolize.dart'; import 'package:flutter_tools/src/commands/symbolize.dart';
import 'package:flutter_tools/src/convert.dart'; import 'package:flutter_tools/src/convert.dart';
...@@ -38,6 +40,24 @@ void main() { ...@@ -38,6 +40,24 @@ void main() {
applyMocksToCommand(command); applyMocksToCommand(command);
}); });
testUsingContext('Regression test for type error in codec', () async {
final DwarfSymbolizationService symbolizationService = DwarfSymbolizationService.test();
final StreamController<List<int>> output = StreamController<List<int>>();
unawaited(symbolizationService.decode(
input: Stream<Uint8List>.fromIterable(<Uint8List>[
utf8.encode('Hello, World\n') as Uint8List,
]),
symbols: Uint8List(0),
output: IOSink(output.sink),
));
await expectLater(
output.stream.transform(utf8.decoder),
emits('Hello, World'),
);
});
testUsingContext('symbolize exits when --debug-info argument is missing', () async { testUsingContext('symbolize exits when --debug-info argument is missing', () async {
final Future<void> result = createTestCommandRunner(command) final Future<void> result = createTestCommandRunner(command)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment