[analyzer] Tidy up much benchmark and integration test code:
* Add a type argument to raw `Future` types (typically `Future<void>`)
* Add type arguments to raw `Map` types (typically Map<String, Object?>`)
* Add a type argument to raw `Completer` constructor calls.
* Use collection-elements in more places.
* Replace an implementation of `String.padLeft` and `String.padRight` with
StringBuffer extension methods that use `String.padLeft` and
`String.padRight`.
* Rename many `sb` variables to `buffer`, which is more idiomatic.
* Move some StringBuffer helper methods to be extensions on StringBuffer.
* Use constructor tear-offs instead of closures which call a constructor.
* Use single quotes where we can.
* Do not prefix constant names with the letter 'k' [1].
* In IntegrationTestMixin:
* Rename to `IntegrationTest`, as it is never used as a mixin.
* Public Stream fields are converted to be getters.
* Private StreamController fields are initialized at their declaration [2],
instead of an initialization method.
* Remove empty zero-parameter constructors.
[1] https://dart.dev/guides/language/effective-dart/style#dont-use-prefix-letters
[2] https://dart.dev/guides/language/effective-dart/usage#do-initialize-fields-at-their-declaration-when-possible
Change-Id: I7a923a80d32f74fbecf42a0fa35ae25285994097
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/281874
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
committed by
Commit Queue
parent
adb321a4b8
commit
bb9371f255
@@ -77,9 +77,9 @@ abstract class Benchmark {
|
||||
|
||||
bool get needsSetup => false;
|
||||
|
||||
Future oneTimeCleanup() => Future.value();
|
||||
Future<void> oneTimeCleanup() => Future.value();
|
||||
|
||||
Future oneTimeSetup() => Future.value();
|
||||
Future<void> oneTimeSetup() => Future.value();
|
||||
|
||||
Future<BenchMarkResult> run({
|
||||
required String dartSdkPath,
|
||||
@@ -87,7 +87,7 @@ abstract class Benchmark {
|
||||
bool verbose = false,
|
||||
});
|
||||
|
||||
Map toJson() =>
|
||||
Map<String, Object?> toJson() =>
|
||||
{'id': id, 'description': description, 'enabled': enabled, 'kind': kind};
|
||||
|
||||
@override
|
||||
@@ -106,7 +106,7 @@ class BenchMarkResult {
|
||||
return BenchMarkResult(kindName, math.min(value, other.value));
|
||||
}
|
||||
|
||||
Map toJson() => {kindName: value};
|
||||
Map<String, Object?> toJson() => {kindName: value};
|
||||
|
||||
@override
|
||||
String toString() => '$kindName: $value';
|
||||
@@ -124,35 +124,32 @@ class CompoundBenchMarkResult extends BenchMarkResult {
|
||||
}
|
||||
|
||||
@override
|
||||
BenchMarkResult combine(BenchMarkResult other) {
|
||||
BenchMarkResult combine(covariant CompoundBenchMarkResult other) {
|
||||
BenchMarkResult combine(BenchMarkResult? a, BenchMarkResult? b) {
|
||||
if (a == null) return b!;
|
||||
if (b == null) return a;
|
||||
return a.combine(b);
|
||||
}
|
||||
|
||||
var o = other as CompoundBenchMarkResult;
|
||||
|
||||
var combined = CompoundBenchMarkResult(name);
|
||||
var keys = (<String>{}
|
||||
..addAll(results.keys)
|
||||
..addAll(o.results.keys))
|
||||
.toList();
|
||||
var keys = {
|
||||
...results.keys,
|
||||
...other.results.keys,
|
||||
}.toList();
|
||||
|
||||
for (var key in keys) {
|
||||
combined.add(key, combine(results[key], o.results[key]));
|
||||
combined.add(key, combine(results[key], other.results[key]));
|
||||
}
|
||||
|
||||
return combined;
|
||||
}
|
||||
|
||||
@override
|
||||
Map toJson() {
|
||||
var m = <String, dynamic>{};
|
||||
for (var entry in results.entries) {
|
||||
m['$name-${entry.key}'] = entry.value.toJson();
|
||||
}
|
||||
return m;
|
||||
Map<String, Object?> toJson() {
|
||||
return {
|
||||
for (var entry in results.entries)
|
||||
'$name-${entry.key}': entry.value.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -186,7 +183,7 @@ class ListCommand extends Command {
|
||||
@override
|
||||
void run() {
|
||||
if (argResults!['machine'] as bool) {
|
||||
var map = <String, dynamic>{
|
||||
var map = <String, Object?>{
|
||||
'benchmarks': benchmarks.map((b) => b.toJson()).toList()
|
||||
};
|
||||
print(JsonEncoder.withIndent(' ').convert(map));
|
||||
|
||||
@@ -13,28 +13,10 @@ import '../../test/integration/support/integration_test_methods.dart';
|
||||
import '../../test/integration/support/integration_tests.dart';
|
||||
import 'operation.dart';
|
||||
|
||||
final SPACE = ' '.codeUnitAt(0);
|
||||
|
||||
void _printColumn(StringBuffer sb, String text, int keyLen,
|
||||
{bool rightJustified = false}) {
|
||||
if (!rightJustified) {
|
||||
sb.write(text);
|
||||
sb.write(',');
|
||||
}
|
||||
for (var i = text.length; i < keyLen; ++i) {
|
||||
sb.writeCharCode(SPACE);
|
||||
}
|
||||
if (rightJustified) {
|
||||
sb.write(text);
|
||||
sb.write(',');
|
||||
}
|
||||
sb.writeCharCode(SPACE);
|
||||
}
|
||||
|
||||
/// [Driver] launches and manages an instance of analysis server,
|
||||
/// reads a stream of operations, sends requests to analysis server
|
||||
/// based upon those operations, and evaluates the results.
|
||||
class Driver extends IntegrationTestMixin {
|
||||
class Driver extends IntegrationTest {
|
||||
/// The amount of time to give the server to respond to a shutdown request
|
||||
/// before forcibly terminating it.
|
||||
static const Duration SHUTDOWN_TIMEOUT = Duration(seconds: 5);
|
||||
@@ -63,30 +45,33 @@ class Driver extends IntegrationTestMixin {
|
||||
Future<Results> get runComplete => _runCompleter.future;
|
||||
|
||||
/// Perform the given operation.
|
||||
///
|
||||
/// Return a [Future] that completes when the next operation can be performed,
|
||||
/// or `null` if the next operation can be performed immediately
|
||||
Future<void>? perform(Operation op) {
|
||||
return op.perform(this);
|
||||
}
|
||||
|
||||
/// Send a command to the server. An 'id' will be automatically assigned.
|
||||
/// The returned [Future] will be completed when the server acknowledges the
|
||||
/// command with a response. If the server acknowledges the command with a
|
||||
/// normal (non-error) response, the future will be completed with the
|
||||
/// 'result' field from the response. If the server acknowledges the command
|
||||
/// with an error response, the future will be completed with an error.
|
||||
/// Send a command to the server.
|
||||
///
|
||||
/// An 'id' will be automatically assigned. The returned [Future] will be
|
||||
/// completed when the server acknowledges the command with a response. If
|
||||
/// the server acknowledges the command with a normal (non-error) response,
|
||||
/// the future will be completed with the 'result' field from the response.
|
||||
/// If the server acknowledges the command with an error response, the future
|
||||
/// will be completed with an error.
|
||||
Future<Map<String, Object?>?> send(
|
||||
String method, Map<String, dynamic> params) {
|
||||
return server.send(method, params);
|
||||
}
|
||||
|
||||
/// Launch the analysis server.
|
||||
///
|
||||
/// Return a [Future] that completes when analysis server has started.
|
||||
Future startServer() async {
|
||||
Future<void> startServer() async {
|
||||
logger.log(Level.FINE, 'starting server');
|
||||
initializeInttestMixin();
|
||||
server = Server();
|
||||
var serverConnected = Completer();
|
||||
var serverConnected = Completer<void>();
|
||||
onServerConnected.listen((_) {
|
||||
logger.log(Level.FINE, 'connected to server');
|
||||
serverConnected.complete();
|
||||
@@ -107,7 +92,7 @@ class Driver extends IntegrationTestMixin {
|
||||
}
|
||||
|
||||
/// Shutdown the analysis server if it is running.
|
||||
Future stopServer([Duration timeout = SHUTDOWN_TIMEOUT]) async {
|
||||
Future<void> stopServer([Duration timeout = SHUTDOWN_TIMEOUT]) async {
|
||||
if (running) {
|
||||
logger.log(Level.FINE, 'requesting server shutdown');
|
||||
// Give the server a short time to comply with the shutdown request; if it
|
||||
@@ -165,19 +150,19 @@ class Measurement {
|
||||
var variance = differenceFromMeanSquared / count;
|
||||
var standardDeviation = sqrt(variance).round();
|
||||
|
||||
var sb = StringBuffer();
|
||||
_printColumn(sb, tag, keyLen);
|
||||
_printColumn(sb, count.toString(), 6, rightJustified: true);
|
||||
_printColumn(sb, errorCount.toString(), 6, rightJustified: true);
|
||||
_printColumn(sb, unexpectedResultCount.toString(), 6, rightJustified: true);
|
||||
_printDuration(sb, Duration(microseconds: meanTime));
|
||||
_printDuration(sb, time90th);
|
||||
_printDuration(sb, time99th);
|
||||
_printDuration(sb, Duration(microseconds: standardDeviation));
|
||||
_printDuration(sb, minTime);
|
||||
_printDuration(sb, maxTime);
|
||||
_printDuration(sb, Duration(microseconds: totalTimeMicros));
|
||||
print(sb.toString());
|
||||
var buffer = StringBuffer();
|
||||
buffer.writePadRight(tag, keyLen);
|
||||
buffer.writePadLeft(count.toString(), 6);
|
||||
buffer.writePadLeft(errorCount.toString(), 6);
|
||||
buffer.writePadLeft(unexpectedResultCount.toString(), 6);
|
||||
buffer.writeDuration(Duration(microseconds: meanTime));
|
||||
buffer.writeDuration(time90th);
|
||||
buffer.writeDuration(time99th);
|
||||
buffer.writeDuration(Duration(microseconds: standardDeviation));
|
||||
buffer.writeDuration(minTime);
|
||||
buffer.writeDuration(maxTime);
|
||||
buffer.writeDuration(Duration(microseconds: totalTimeMicros));
|
||||
print(buffer.toString());
|
||||
}
|
||||
|
||||
void record(bool success, Duration elapsed) {
|
||||
@@ -190,15 +175,10 @@ class Measurement {
|
||||
void recordUnexpectedResults() {
|
||||
++unexpectedResultCount;
|
||||
}
|
||||
|
||||
void _printDuration(StringBuffer sb, Duration duration) {
|
||||
_printColumn(sb, duration.inMilliseconds.toString(), 15,
|
||||
rightJustified: true);
|
||||
}
|
||||
}
|
||||
|
||||
/// [Results] contains information gathered by [Driver]
|
||||
/// while running the analysis server
|
||||
/// [Results] contains information gathered by [Driver] while running the
|
||||
/// analysis server.
|
||||
class Results {
|
||||
Map<String, Measurement> measurements = <String, Measurement>{};
|
||||
|
||||
@@ -236,7 +216,7 @@ class Results {
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO(danrubel) *** print warnings if driver caches are not empty ****
|
||||
// TODO(danrubel): print warnings if driver caches are not empty.
|
||||
print('''
|
||||
|
||||
(1) uxr = UneXpected Results or responses received from the server
|
||||
@@ -259,31 +239,46 @@ class Results {
|
||||
measurements[tag]!.recordUnexpectedResults();
|
||||
}
|
||||
|
||||
void _printGroupHeader(String groupName, int keyLen) {
|
||||
var sb = StringBuffer();
|
||||
_printColumn(sb, groupName, keyLen);
|
||||
_printColumn(sb, 'count', 6, rightJustified: true);
|
||||
_printColumn(sb, 'error', 6, rightJustified: true);
|
||||
_printColumn(sb, 'uxr(1)', 6, rightJustified: true);
|
||||
sb.write(' ');
|
||||
_printColumn(sb, 'mean(2)', 15);
|
||||
_printColumn(sb, '90th', 15);
|
||||
_printColumn(sb, '99th', 15);
|
||||
_printColumn(sb, 'std-dev', 15);
|
||||
_printColumn(sb, 'minimum', 15);
|
||||
_printColumn(sb, 'maximum', 15);
|
||||
_printColumn(sb, 'total', 15);
|
||||
print(sb.toString());
|
||||
static void _printGroupHeader(String groupName, int keyLength) {
|
||||
var buffer = StringBuffer();
|
||||
buffer.writePadRight(groupName, keyLength);
|
||||
buffer.writePadLeft('count', 6);
|
||||
buffer.writePadLeft('error', 6);
|
||||
buffer.writePadLeft('uxr(1)', 6);
|
||||
buffer.write(' ');
|
||||
buffer.writePadRight('mean(2)', 15);
|
||||
buffer.writePadRight('90th', 15);
|
||||
buffer.writePadRight('99th', 15);
|
||||
buffer.writePadRight('std-dev', 15);
|
||||
buffer.writePadRight('minimum', 15);
|
||||
buffer.writePadRight('maximum', 15);
|
||||
buffer.writePadRight('total', 15);
|
||||
print(buffer.toString());
|
||||
}
|
||||
|
||||
void _printTotals(int keyLen, int totalCount, int totalErrorCount,
|
||||
static void _printTotals(int keyLength, int totalCount, int totalErrorCount,
|
||||
int totalUnexpectedResultCount) {
|
||||
var sb = StringBuffer();
|
||||
_printColumn(sb, 'Totals', keyLen);
|
||||
_printColumn(sb, totalCount.toString(), 6, rightJustified: true);
|
||||
_printColumn(sb, totalErrorCount.toString(), 6, rightJustified: true);
|
||||
_printColumn(sb, totalUnexpectedResultCount.toString(), 6,
|
||||
rightJustified: true);
|
||||
print(sb.toString());
|
||||
var buffer = StringBuffer();
|
||||
buffer.writePadRight('Totals', keyLength);
|
||||
buffer.writePadLeft(totalCount.toString(), 6);
|
||||
buffer.writePadLeft(totalErrorCount.toString(), 6);
|
||||
buffer.writePadLeft(totalUnexpectedResultCount.toString(), 6);
|
||||
print(buffer.toString());
|
||||
}
|
||||
}
|
||||
|
||||
extension on StringBuffer {
|
||||
void writeDuration(Duration duration) {
|
||||
writePadLeft(duration.inMilliseconds.toString(), 15);
|
||||
}
|
||||
|
||||
void writePadLeft(String text, int keyLength) {
|
||||
write(text.padLeft(keyLength, ' '));
|
||||
write(' ');
|
||||
}
|
||||
|
||||
void writePadRight(String text, int keyLength) {
|
||||
write(text.padRight(keyLength, ' '));
|
||||
write(' ');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,14 +170,14 @@ class ResponseOperation extends Operation {
|
||||
|
||||
class StartServerOperation extends Operation {
|
||||
@override
|
||||
Future perform(Driver driver) {
|
||||
Future<void> perform(Driver driver) {
|
||||
return driver.startServer();
|
||||
}
|
||||
}
|
||||
|
||||
class WaitForAnalysisCompleteOperation extends Operation {
|
||||
@override
|
||||
Future perform(Driver driver) {
|
||||
Future<void> perform(Driver driver) {
|
||||
var start = DateTime.now();
|
||||
driver.logger.log(Level.FINE, 'waiting for analysis to complete');
|
||||
late StreamSubscription<ServerStatusParams> subscription;
|
||||
|
||||
@@ -76,7 +76,7 @@ class AnalysisBenchmark extends Benchmark {
|
||||
var completionCount = 0;
|
||||
var stopwatch = Stopwatch()..start();
|
||||
|
||||
Future complete(int offset) async {
|
||||
Future<void> complete(int offset) async {
|
||||
await test.complete(filePath, offset, isWarmUp: false);
|
||||
completionCount++;
|
||||
}
|
||||
@@ -191,10 +191,10 @@ class ColdAnalysisBenchmark extends Benchmark {
|
||||
}
|
||||
|
||||
class ServerBenchmark {
|
||||
static final das = ServerBenchmark('analysis-server', 'Analysis Server',
|
||||
() => AnalysisServerBenchmarkTest());
|
||||
static final das = ServerBenchmark(
|
||||
'analysis-server', 'Analysis Server', AnalysisServerBenchmarkTest.new);
|
||||
static final lsp = ServerBenchmark('lsp-analysis-server',
|
||||
'LSP Analysis Server', () => LspAnalysisServerBenchmarkTest());
|
||||
'LSP Analysis Server', LspAnalysisServerBenchmarkTest.new);
|
||||
final String id;
|
||||
|
||||
final String name;
|
||||
|
||||
@@ -120,15 +120,15 @@ class CmdLineSeveralProjectsBenchmark extends AbstractCmdLineBenchmark {
|
||||
|
||||
@override
|
||||
List<String> analyzeWhat(bool quick) => quick
|
||||
? ["meta"]
|
||||
? ['meta']
|
||||
: [
|
||||
"analysis_server",
|
||||
"analysis_server_client",
|
||||
"analyzer",
|
||||
"analyzer_cli",
|
||||
"analyzer_plugin",
|
||||
"analyzer_utilities",
|
||||
"_fe_analyzer_shared",
|
||||
'analysis_server',
|
||||
'analysis_server_client',
|
||||
'analyzer',
|
||||
'analyzer_cli',
|
||||
'analyzer_plugin',
|
||||
'analyzer_utilities',
|
||||
'_fe_analyzer_shared',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ class CmdLineSmallFileBenchmark extends AbstractCmdLineBenchmark {
|
||||
String get workingDir => _tempDir!.path;
|
||||
|
||||
@override
|
||||
List<String> analyzeWhat(bool quick) => ["t.dart"];
|
||||
List<String> analyzeWhat(bool quick) => ['t.dart'];
|
||||
|
||||
@override
|
||||
void cleanup() {
|
||||
@@ -154,12 +154,12 @@ class CmdLineSmallFileBenchmark extends AbstractCmdLineBenchmark {
|
||||
|
||||
@override
|
||||
void setup() {
|
||||
var dir = Directory.systemTemp.createTempSync("analyzer-benchmark");
|
||||
var file = File.fromUri(dir.uri.resolve("t.dart"));
|
||||
file.writeAsStringSync("""
|
||||
var dir = Directory.systemTemp.createTempSync('analyzer-benchmark');
|
||||
var file = File.fromUri(dir.uri.resolve('t.dart'));
|
||||
file.writeAsStringSync('''
|
||||
void main() {
|
||||
print("Hello, world!");
|
||||
}""");
|
||||
}''');
|
||||
_tempDir = dir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ import 'memory_tests.dart';
|
||||
class FlutterCompletionBenchmark extends Benchmark implements FlutterBenchmark {
|
||||
static final das = FlutterCompletionBenchmark(
|
||||
'das',
|
||||
() => AnalysisServerBenchmarkTest(),
|
||||
AnalysisServerBenchmarkTest.new,
|
||||
);
|
||||
|
||||
static final lsp = FlutterCompletionBenchmark(
|
||||
'lsp',
|
||||
() => LspAnalysisServerBenchmarkTest(),
|
||||
LspAnalysisServerBenchmarkTest.new,
|
||||
);
|
||||
|
||||
final AbstractBenchmarkTest Function() testConstructor;
|
||||
@@ -240,20 +240,20 @@ class FlutterCompletionBenchmark extends Benchmark implements FlutterBenchmark {
|
||||
// Perform warm-up.
|
||||
// The cold start does not matter.
|
||||
// The sustained performance is much more important.
|
||||
const kWarmUpCount = 5;
|
||||
for (var i = 0; i < kWarmUpCount; i++) {
|
||||
const warmUpCount = 5;
|
||||
for (var i = 0; i < warmUpCount; i++) {
|
||||
await perform(isWarmUp: true);
|
||||
}
|
||||
|
||||
const kRepeatCount = 5;
|
||||
const repeatCount = 5;
|
||||
final timer = Stopwatch()..start();
|
||||
for (var i = 0; i < kRepeatCount; i++) {
|
||||
for (var i = 0; i < repeatCount; i++) {
|
||||
await perform(isWarmUp: false);
|
||||
}
|
||||
|
||||
await test.closeFile(filePath);
|
||||
|
||||
return timer.elapsedMicroseconds ~/ kRepeatCount;
|
||||
return timer.elapsedMicroseconds ~/ repeatCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -274,21 +274,21 @@ class ServiceProtocol {
|
||||
var id = '${++_id}';
|
||||
var completer = Completer<Map>();
|
||||
_completers[id] = completer;
|
||||
var m = <String, dynamic>{
|
||||
var messageMap = <String, dynamic>{
|
||||
'jsonrpc': '2.0',
|
||||
'id': id,
|
||||
'method': method,
|
||||
'args': args
|
||||
'args': args,
|
||||
'params': args,
|
||||
};
|
||||
m['params'] = args;
|
||||
var message = jsonEncode(m);
|
||||
var message = jsonEncode(messageMap);
|
||||
socket.add(message);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future dispose() => socket.close();
|
||||
Future<void> dispose() => socket.close();
|
||||
|
||||
void _handleMessage(dynamic message) {
|
||||
void _handleMessage(Object? message) {
|
||||
if (message is! String) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class DeleteContextTest extends AbstractAnalysisServerIntegrationTest {
|
||||
await sendExecutionMapUri(contextId, uri: 'package:test/main.dart');
|
||||
expect(result.file, pathname);
|
||||
|
||||
expect(await sendExecutionDeleteContext(contextId), isNull);
|
||||
await sendExecutionDeleteContext(contextId);
|
||||
|
||||
// After the delete, expect this to fail.
|
||||
try {
|
||||
|
||||
@@ -11,14 +11,14 @@ import 'dart:async';
|
||||
|
||||
import 'package:analysis_server/protocol/protocol_generated.dart';
|
||||
import 'package:analysis_server/src/protocol/protocol_internal.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'integration_tests.dart';
|
||||
import 'protocol_matchers.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
|
||||
/// Convenience methods for running integration tests.
|
||||
abstract class IntegrationTestMixin {
|
||||
/// Base implementation for running integration tests.
|
||||
abstract class IntegrationTest {
|
||||
Server get server;
|
||||
|
||||
/// Return the version number of the analysis server.
|
||||
@@ -39,10 +39,9 @@ abstract class IntegrationTestMixin {
|
||||
/// this request, but for which a response has not yet been sent, will not be
|
||||
/// responded to. No further responses or notifications will be sent after
|
||||
/// the response to this request has been sent.
|
||||
Future sendServerShutdown() async {
|
||||
Future<void> sendServerShutdown() async {
|
||||
var result = await server.send('server.shutdown', null);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Subscribe for services. All previous subscriptions are replaced by the
|
||||
@@ -57,11 +56,11 @@ abstract class IntegrationTestMixin {
|
||||
/// subscriptions: List<ServerService>
|
||||
///
|
||||
/// A list of the services being subscribed to.
|
||||
Future sendServerSetSubscriptions(List<ServerService> subscriptions) async {
|
||||
Future<void> sendServerSetSubscriptions(
|
||||
List<ServerService> subscriptions) async {
|
||||
var params = ServerSetSubscriptionsParams(subscriptions).toJson();
|
||||
var result = await server.send('server.setSubscriptions', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Requests cancellation of a request sent by the client by id. This is
|
||||
@@ -77,11 +76,10 @@ abstract class IntegrationTestMixin {
|
||||
/// id: String
|
||||
///
|
||||
/// The id of the request that should be cancelled.
|
||||
Future sendServerCancelRequest(String id) async {
|
||||
Future<void> sendServerCancelRequest(String id) async {
|
||||
var params = ServerCancelRequestParams(id).toJson();
|
||||
var result = await server.send('server.cancelRequest', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Reports that the server is running. This notification is issued once
|
||||
@@ -99,10 +97,12 @@ abstract class IntegrationTestMixin {
|
||||
/// pid: int
|
||||
///
|
||||
/// The process id of the analysis server process.
|
||||
late Stream<ServerConnectedParams> onServerConnected;
|
||||
late final Stream<ServerConnectedParams> onServerConnected =
|
||||
_onServerConnected.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onServerConnected].
|
||||
late StreamController<ServerConnectedParams> _onServerConnected;
|
||||
final _onServerConnected =
|
||||
StreamController<ServerConnectedParams>(sync: true);
|
||||
|
||||
/// Reports that an unexpected error has occurred while executing the server.
|
||||
/// This notification is not used for problems with specific requests (which
|
||||
@@ -127,20 +127,22 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// The stack trace associated with the generation of the error, used for
|
||||
/// debugging the server.
|
||||
late Stream<ServerErrorParams> onServerError;
|
||||
late final Stream<ServerErrorParams> onServerError =
|
||||
_onServerError.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onServerError].
|
||||
late StreamController<ServerErrorParams> _onServerError;
|
||||
final _onServerError = StreamController<ServerErrorParams>(sync: true);
|
||||
|
||||
/// The stream of entries describing events happened in the server.
|
||||
///
|
||||
/// Parameters
|
||||
///
|
||||
/// entry: ServerLogEntry
|
||||
late Stream<ServerLogParams> onServerLog;
|
||||
late final Stream<ServerLogParams> onServerLog =
|
||||
_onServerLog.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onServerLog].
|
||||
late StreamController<ServerLogParams> _onServerLog;
|
||||
final _onServerLog = StreamController<ServerLogParams>(sync: true);
|
||||
|
||||
/// Reports the current status of the server. Parameters are omitted if there
|
||||
/// has been no change in the status represented by that parameter.
|
||||
@@ -163,10 +165,11 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// Note: this status type is deprecated, and is no longer sent by the
|
||||
/// server.
|
||||
late Stream<ServerStatusParams> onServerStatus;
|
||||
late final Stream<ServerStatusParams> onServerStatus =
|
||||
_onServerStatus.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onServerStatus].
|
||||
late StreamController<ServerStatusParams> _onServerStatus;
|
||||
final _onServerStatus = StreamController<ServerStatusParams>(sync: true);
|
||||
|
||||
/// Return the errors associated with the given file. If the errors for the
|
||||
/// given file have not yet been computed, or the most recently computed
|
||||
@@ -452,10 +455,9 @@ abstract class IntegrationTestMixin {
|
||||
/// Force re-reading of all potentially changed files, re-resolving of all
|
||||
/// referenced URIs, and corresponding re-analysis of everything affected in
|
||||
/// the current analysis roots.
|
||||
Future sendAnalysisReanalyze() async {
|
||||
Future<void> sendAnalysisReanalyze() async {
|
||||
var result = await server.send('analysis.reanalyze', null);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Sets the root paths used to determine which files to analyze. The set of
|
||||
@@ -509,7 +511,7 @@ abstract class IntegrationTestMixin {
|
||||
/// their package: URI's resolved using the normal pubspec.yaml mechanism.
|
||||
/// If this field is absent, or the empty map is specified, that indicates
|
||||
/// that the normal pubspec.yaml mechanism should always be used.
|
||||
Future sendAnalysisSetAnalysisRoots(
|
||||
Future<void> sendAnalysisSetAnalysisRoots(
|
||||
List<String> included, List<String> excluded,
|
||||
{Map<String, String>? packageRoots}) async {
|
||||
var params = AnalysisSetAnalysisRootsParams(included, excluded,
|
||||
@@ -517,7 +519,6 @@ abstract class IntegrationTestMixin {
|
||||
.toJson();
|
||||
var result = await server.send('analysis.setAnalysisRoots', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Subscribe for general services (that is, services that are not specific
|
||||
@@ -533,12 +534,11 @@ abstract class IntegrationTestMixin {
|
||||
/// subscriptions: List<GeneralAnalysisService>
|
||||
///
|
||||
/// A list of the services being subscribed to.
|
||||
Future sendAnalysisSetGeneralSubscriptions(
|
||||
Future<void> sendAnalysisSetGeneralSubscriptions(
|
||||
List<GeneralAnalysisService> subscriptions) async {
|
||||
var params = AnalysisSetGeneralSubscriptionsParams(subscriptions).toJson();
|
||||
var result = await server.send('analysis.setGeneralSubscriptions', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Set the priority files to the files in the given list. A priority file is
|
||||
@@ -564,11 +564,10 @@ abstract class IntegrationTestMixin {
|
||||
/// files: List<FilePath>
|
||||
///
|
||||
/// The files that are to be a priority for analysis.
|
||||
Future sendAnalysisSetPriorityFiles(List<String> files) async {
|
||||
Future<void> sendAnalysisSetPriorityFiles(List<String> files) async {
|
||||
var params = AnalysisSetPriorityFilesParams(files).toJson();
|
||||
var result = await server.send('analysis.setPriorityFiles', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Subscribe for services that are specific to individual files. All
|
||||
@@ -601,12 +600,11 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// A table mapping services to a list of the files being subscribed to the
|
||||
/// service.
|
||||
Future sendAnalysisSetSubscriptions(
|
||||
Future<void> sendAnalysisSetSubscriptions(
|
||||
Map<AnalysisService, List<String>> subscriptions) async {
|
||||
var params = AnalysisSetSubscriptionsParams(subscriptions).toJson();
|
||||
var result = await server.send('analysis.setSubscriptions', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Update the content of one or more files. Files that were previously
|
||||
@@ -647,11 +645,10 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// The options that are to be used to control analysis.
|
||||
@deprecated
|
||||
Future sendAnalysisUpdateOptions(AnalysisOptions options) async {
|
||||
Future<void> sendAnalysisUpdateOptions(AnalysisOptions options) async {
|
||||
var params = AnalysisUpdateOptionsParams(options).toJson();
|
||||
var result = await server.send('analysis.updateOptions', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Reports the paths of the files that are being analyzed.
|
||||
@@ -665,10 +662,12 @@ abstract class IntegrationTestMixin {
|
||||
/// directories: List<FilePath>
|
||||
///
|
||||
/// A list of the paths of the files that are being analyzed.
|
||||
late Stream<AnalysisAnalyzedFilesParams> onAnalysisAnalyzedFiles;
|
||||
late final Stream<AnalysisAnalyzedFilesParams> onAnalysisAnalyzedFiles =
|
||||
_onAnalysisAnalyzedFiles.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisAnalyzedFiles].
|
||||
late StreamController<AnalysisAnalyzedFilesParams> _onAnalysisAnalyzedFiles;
|
||||
final _onAnalysisAnalyzedFiles =
|
||||
StreamController<AnalysisAnalyzedFilesParams>(sync: true);
|
||||
|
||||
/// Reports closing labels relevant to a given file.
|
||||
///
|
||||
@@ -691,10 +690,12 @@ abstract class IntegrationTestMixin {
|
||||
/// constructor/method calls and List arguments that span multiple lines.
|
||||
/// Note that the ranges that are returned can overlap each other because
|
||||
/// they may be associated with constructs that can be nested.
|
||||
late Stream<AnalysisClosingLabelsParams> onAnalysisClosingLabels;
|
||||
late final Stream<AnalysisClosingLabelsParams> onAnalysisClosingLabels =
|
||||
_onAnalysisClosingLabels.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisClosingLabels].
|
||||
late StreamController<AnalysisClosingLabelsParams> _onAnalysisClosingLabels;
|
||||
final _onAnalysisClosingLabels =
|
||||
StreamController<AnalysisClosingLabelsParams>(sync: true);
|
||||
|
||||
/// Reports the errors associated with a given file. The set of errors
|
||||
/// included in the notification is always a complete list that supersedes
|
||||
@@ -709,10 +710,11 @@ abstract class IntegrationTestMixin {
|
||||
/// errors: List<AnalysisError>
|
||||
///
|
||||
/// The errors contained in the file.
|
||||
late Stream<AnalysisErrorsParams> onAnalysisErrors;
|
||||
late final Stream<AnalysisErrorsParams> onAnalysisErrors =
|
||||
_onAnalysisErrors.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisErrors].
|
||||
late StreamController<AnalysisErrorsParams> _onAnalysisErrors;
|
||||
final _onAnalysisErrors = StreamController<AnalysisErrorsParams>(sync: true);
|
||||
|
||||
/// Reports that any analysis results that were previously associated with
|
||||
/// the given files should be considered to be invalid because those files
|
||||
@@ -732,10 +734,12 @@ abstract class IntegrationTestMixin {
|
||||
/// files: List<FilePath>
|
||||
///
|
||||
/// The files that are no longer being analyzed.
|
||||
late Stream<AnalysisFlushResultsParams> onAnalysisFlushResults;
|
||||
late final Stream<AnalysisFlushResultsParams> onAnalysisFlushResults =
|
||||
_onAnalysisFlushResults.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisFlushResults].
|
||||
late StreamController<AnalysisFlushResultsParams> _onAnalysisFlushResults;
|
||||
final _onAnalysisFlushResults =
|
||||
StreamController<AnalysisFlushResultsParams>(sync: true);
|
||||
|
||||
/// Reports the folding regions associated with a given file. Folding regions
|
||||
/// can be nested, but will not be overlapping. Nesting occurs when a
|
||||
@@ -755,10 +759,12 @@ abstract class IntegrationTestMixin {
|
||||
/// regions: List<FoldingRegion>
|
||||
///
|
||||
/// The folding regions contained in the file.
|
||||
late Stream<AnalysisFoldingParams> onAnalysisFolding;
|
||||
late final Stream<AnalysisFoldingParams> onAnalysisFolding =
|
||||
_onAnalysisFolding.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisFolding].
|
||||
late StreamController<AnalysisFoldingParams> _onAnalysisFolding;
|
||||
final _onAnalysisFolding =
|
||||
StreamController<AnalysisFoldingParams>(sync: true);
|
||||
|
||||
/// Reports the highlight regions associated with a given file.
|
||||
///
|
||||
@@ -779,10 +785,12 @@ abstract class IntegrationTestMixin {
|
||||
/// some range. Note that the highlight regions that are returned can
|
||||
/// overlap other highlight regions if there is more than one meaning
|
||||
/// associated with a particular region.
|
||||
late Stream<AnalysisHighlightsParams> onAnalysisHighlights;
|
||||
late final Stream<AnalysisHighlightsParams> onAnalysisHighlights =
|
||||
_onAnalysisHighlights.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisHighlights].
|
||||
late StreamController<AnalysisHighlightsParams> _onAnalysisHighlights;
|
||||
final _onAnalysisHighlights =
|
||||
StreamController<AnalysisHighlightsParams>(sync: true);
|
||||
|
||||
/// Reports the classes that are implemented or extended and class members
|
||||
/// that are implemented or overridden in a file.
|
||||
@@ -804,10 +812,12 @@ abstract class IntegrationTestMixin {
|
||||
/// members: List<ImplementedMember>
|
||||
///
|
||||
/// The member defined in the file that are implemented or overridden.
|
||||
late Stream<AnalysisImplementedParams> onAnalysisImplemented;
|
||||
late final Stream<AnalysisImplementedParams> onAnalysisImplemented =
|
||||
_onAnalysisImplemented.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisImplemented].
|
||||
late StreamController<AnalysisImplementedParams> _onAnalysisImplemented;
|
||||
final _onAnalysisImplemented =
|
||||
StreamController<AnalysisImplementedParams>(sync: true);
|
||||
|
||||
/// Reports that the navigation information associated with a region of a
|
||||
/// single file has become invalid and should be re-requested.
|
||||
@@ -835,10 +845,12 @@ abstract class IntegrationTestMixin {
|
||||
/// The delta to be applied to the offsets in information that follows the
|
||||
/// invalidated region in order to update it so that it doesn't need to be
|
||||
/// re-requested.
|
||||
late Stream<AnalysisInvalidateParams> onAnalysisInvalidate;
|
||||
late final Stream<AnalysisInvalidateParams> onAnalysisInvalidate =
|
||||
_onAnalysisInvalidate.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisInvalidate].
|
||||
late StreamController<AnalysisInvalidateParams> _onAnalysisInvalidate;
|
||||
final _onAnalysisInvalidate =
|
||||
StreamController<AnalysisInvalidateParams>(sync: true);
|
||||
|
||||
/// Reports the navigation targets associated with a given file.
|
||||
///
|
||||
@@ -871,10 +883,12 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// The files containing navigation targets referenced in the file. They
|
||||
/// are referenced by NavigationTargets by their index in this array.
|
||||
late Stream<AnalysisNavigationParams> onAnalysisNavigation;
|
||||
late final Stream<AnalysisNavigationParams> onAnalysisNavigation =
|
||||
_onAnalysisNavigation.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisNavigation].
|
||||
late StreamController<AnalysisNavigationParams> _onAnalysisNavigation;
|
||||
final _onAnalysisNavigation =
|
||||
StreamController<AnalysisNavigationParams>(sync: true);
|
||||
|
||||
/// Reports the occurrences of references to elements within a single file.
|
||||
///
|
||||
@@ -891,10 +905,12 @@ abstract class IntegrationTestMixin {
|
||||
/// occurrences: List<Occurrences>
|
||||
///
|
||||
/// The occurrences of references to elements within the file.
|
||||
late Stream<AnalysisOccurrencesParams> onAnalysisOccurrences;
|
||||
late final Stream<AnalysisOccurrencesParams> onAnalysisOccurrences =
|
||||
_onAnalysisOccurrences.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisOccurrences].
|
||||
late StreamController<AnalysisOccurrencesParams> _onAnalysisOccurrences;
|
||||
final _onAnalysisOccurrences =
|
||||
StreamController<AnalysisOccurrencesParams>(sync: true);
|
||||
|
||||
/// Reports the outline associated with a single file.
|
||||
///
|
||||
@@ -923,10 +939,12 @@ abstract class IntegrationTestMixin {
|
||||
/// outline: Outline
|
||||
///
|
||||
/// The outline associated with the file.
|
||||
late Stream<AnalysisOutlineParams> onAnalysisOutline;
|
||||
late final Stream<AnalysisOutlineParams> onAnalysisOutline =
|
||||
_onAnalysisOutline.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisOutline].
|
||||
late StreamController<AnalysisOutlineParams> _onAnalysisOutline;
|
||||
final _onAnalysisOutline =
|
||||
StreamController<AnalysisOutlineParams>(sync: true);
|
||||
|
||||
/// Reports the overriding members in a file.
|
||||
///
|
||||
@@ -943,10 +961,12 @@ abstract class IntegrationTestMixin {
|
||||
/// overrides: List<Override>
|
||||
///
|
||||
/// The overrides associated with the file.
|
||||
late Stream<AnalysisOverridesParams> onAnalysisOverrides;
|
||||
late final Stream<AnalysisOverridesParams> onAnalysisOverrides =
|
||||
_onAnalysisOverrides.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onAnalysisOverrides].
|
||||
late StreamController<AnalysisOverridesParams> _onAnalysisOverrides;
|
||||
final _onAnalysisOverrides =
|
||||
StreamController<AnalysisOverridesParams>(sync: true);
|
||||
|
||||
/// Request that completion suggestions for the given offset in the given
|
||||
/// file be returned.
|
||||
@@ -1062,12 +1082,11 @@ abstract class IntegrationTestMixin {
|
||||
/// subscriptions: List<CompletionService>
|
||||
///
|
||||
/// A list of the services being subscribed to.
|
||||
Future sendCompletionSetSubscriptions(
|
||||
Future<void> sendCompletionSetSubscriptions(
|
||||
List<CompletionService> subscriptions) async {
|
||||
var params = CompletionSetSubscriptionsParams(subscriptions).toJson();
|
||||
var result = await server.send('completion.setSubscriptions', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The client can make this request to express interest in certain libraries
|
||||
@@ -1087,11 +1106,11 @@ abstract class IntegrationTestMixin {
|
||||
/// suggestions. If one configured path is beneath another, the descendant
|
||||
/// will override the ancestors' configured libraries of interest.
|
||||
@deprecated
|
||||
Future sendCompletionRegisterLibraryPaths(List<LibraryPathSet> paths) async {
|
||||
Future<void> sendCompletionRegisterLibraryPaths(
|
||||
List<LibraryPathSet> paths) async {
|
||||
var params = CompletionRegisterLibraryPathsParams(paths).toJson();
|
||||
var result = await server.send('completion.registerLibraryPaths', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Clients must make this request when the user has selected a completion
|
||||
@@ -1267,10 +1286,12 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// If an AvailableSuggestion has relevance tags that match more than one
|
||||
/// IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
|
||||
late Stream<CompletionResultsParams> onCompletionResults;
|
||||
late final Stream<CompletionResultsParams> onCompletionResults =
|
||||
_onCompletionResults.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onCompletionResults].
|
||||
late StreamController<CompletionResultsParams> _onCompletionResults;
|
||||
final _onCompletionResults =
|
||||
StreamController<CompletionResultsParams>(sync: true);
|
||||
|
||||
/// Reports the pre-computed, candidate completions from symbols defined in a
|
||||
/// corresponding library. This notification may be sent multiple times. When
|
||||
@@ -1290,12 +1311,13 @@ abstract class IntegrationTestMixin {
|
||||
/// removedLibraries: List<int> (optional)
|
||||
///
|
||||
/// A list of library ids that no longer apply.
|
||||
late Stream<CompletionAvailableSuggestionsParams>
|
||||
onCompletionAvailableSuggestions;
|
||||
late final Stream<CompletionAvailableSuggestionsParams>
|
||||
onCompletionAvailableSuggestions =
|
||||
_onCompletionAvailableSuggestions.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onCompletionAvailableSuggestions].
|
||||
late StreamController<CompletionAvailableSuggestionsParams>
|
||||
_onCompletionAvailableSuggestions;
|
||||
final _onCompletionAvailableSuggestions =
|
||||
StreamController<CompletionAvailableSuggestionsParams>(sync: true);
|
||||
|
||||
/// Reports existing imports in a library. This notification may be sent
|
||||
/// multiple times for a library. When a notification is processed, clients
|
||||
@@ -1310,11 +1332,13 @@ abstract class IntegrationTestMixin {
|
||||
/// imports: ExistingImports
|
||||
///
|
||||
/// The existing imports in the library.
|
||||
late Stream<CompletionExistingImportsParams> onCompletionExistingImports;
|
||||
late final Stream<CompletionExistingImportsParams>
|
||||
onCompletionExistingImports =
|
||||
_onCompletionExistingImports.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onCompletionExistingImports].
|
||||
late StreamController<CompletionExistingImportsParams>
|
||||
_onCompletionExistingImports;
|
||||
final _onCompletionExistingImports =
|
||||
StreamController<CompletionExistingImportsParams>(sync: true);
|
||||
|
||||
/// Perform a search for references to the element defined or referenced at
|
||||
/// the given offset in the given file.
|
||||
@@ -1548,10 +1572,11 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// True if this is that last set of results that will be returned for the
|
||||
/// indicated search.
|
||||
late Stream<SearchResultsParams> onSearchResults;
|
||||
late final Stream<SearchResultsParams> onSearchResults =
|
||||
_onSearchResults.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onSearchResults].
|
||||
late StreamController<SearchResultsParams> _onSearchResults;
|
||||
final _onSearchResults = StreamController<SearchResultsParams>(sync: true);
|
||||
|
||||
/// Format the contents of a single file. The currently selected region of
|
||||
/// text is passed in so that the selection can be preserved across the
|
||||
@@ -2141,11 +2166,10 @@ abstract class IntegrationTestMixin {
|
||||
/// id: ExecutionContextId
|
||||
///
|
||||
/// The identifier of the execution context that is to be deleted.
|
||||
Future sendExecutionDeleteContext(String id) async {
|
||||
Future<void> sendExecutionDeleteContext(String id) async {
|
||||
var params = ExecutionDeleteContextParams(id).toJson();
|
||||
var result = await server.send('execution.deleteContext', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Request completion suggestions for the given runtime context.
|
||||
@@ -2306,12 +2330,11 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// A list of the services being subscribed to.
|
||||
@deprecated
|
||||
Future sendExecutionSetSubscriptions(
|
||||
Future<void> sendExecutionSetSubscriptions(
|
||||
List<ExecutionService> subscriptions) async {
|
||||
var params = ExecutionSetSubscriptionsParams(subscriptions).toJson();
|
||||
var result = await server.send('execution.setSubscriptions', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Reports information needed to allow a single file to be launched.
|
||||
@@ -2336,10 +2359,12 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// A list of the Dart files that are referenced by the file. This field is
|
||||
/// omitted if the file is not an HTML file.
|
||||
late Stream<ExecutionLaunchDataParams> onExecutionLaunchData;
|
||||
late final Stream<ExecutionLaunchDataParams> onExecutionLaunchData =
|
||||
_onExecutionLaunchData.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onExecutionLaunchData].
|
||||
late StreamController<ExecutionLaunchDataParams> _onExecutionLaunchData;
|
||||
final _onExecutionLaunchData =
|
||||
StreamController<ExecutionLaunchDataParams>(sync: true);
|
||||
|
||||
/// Return server diagnostics.
|
||||
///
|
||||
@@ -2407,11 +2432,10 @@ abstract class IntegrationTestMixin {
|
||||
/// value: bool
|
||||
///
|
||||
/// Enable or disable analytics.
|
||||
Future sendAnalyticsEnable(bool value) async {
|
||||
Future<void> sendAnalyticsEnable(bool value) async {
|
||||
var params = AnalyticsEnableParams(value).toJson();
|
||||
var result = await server.send('analytics.enable', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Send information about client events.
|
||||
@@ -2432,11 +2456,10 @@ abstract class IntegrationTestMixin {
|
||||
/// action: String
|
||||
///
|
||||
/// The value used to indicate which action was performed.
|
||||
Future sendAnalyticsSendEvent(String action) async {
|
||||
Future<void> sendAnalyticsSendEvent(String action) async {
|
||||
var params = AnalyticsSendEventParams(action).toJson();
|
||||
var result = await server.send('analytics.sendEvent', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Send timing information for client events (e.g. code completions).
|
||||
@@ -2460,11 +2483,10 @@ abstract class IntegrationTestMixin {
|
||||
/// millis: int
|
||||
///
|
||||
/// The duration of the event in milliseconds.
|
||||
Future sendAnalyticsSendTiming(String event, int millis) async {
|
||||
Future<void> sendAnalyticsSendTiming(String event, int millis) async {
|
||||
var params = AnalyticsSendTimingParams(event, millis).toJson();
|
||||
var result = await server.send('analytics.sendTiming', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Return the description of the widget instance at the given location.
|
||||
@@ -2578,12 +2600,11 @@ abstract class IntegrationTestMixin {
|
||||
///
|
||||
/// A table mapping services to a list of the files being subscribed to the
|
||||
/// service.
|
||||
Future sendFlutterSetSubscriptions(
|
||||
Future<void> sendFlutterSetSubscriptions(
|
||||
Map<FlutterService, List<String>> subscriptions) async {
|
||||
var params = FlutterSetSubscriptionsParams(subscriptions).toJson();
|
||||
var result = await server.send('flutter.setSubscriptions', params);
|
||||
outOfTestExpect(result, isNull);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Reports the Flutter outline associated with a single file.
|
||||
@@ -2601,76 +2622,11 @@ abstract class IntegrationTestMixin {
|
||||
/// outline: FlutterOutline
|
||||
///
|
||||
/// The outline associated with the file.
|
||||
late Stream<FlutterOutlineParams> onFlutterOutline;
|
||||
late final Stream<FlutterOutlineParams> onFlutterOutline =
|
||||
_onFlutterOutline.stream.asBroadcastStream();
|
||||
|
||||
/// Stream controller for [onFlutterOutline].
|
||||
late StreamController<FlutterOutlineParams> _onFlutterOutline;
|
||||
|
||||
/// Initialize the fields in InttestMixin, and ensure that notifications will
|
||||
/// be handled.
|
||||
void initializeInttestMixin() {
|
||||
_onServerConnected = StreamController<ServerConnectedParams>(sync: true);
|
||||
onServerConnected = _onServerConnected.stream.asBroadcastStream();
|
||||
_onServerError = StreamController<ServerErrorParams>(sync: true);
|
||||
onServerError = _onServerError.stream.asBroadcastStream();
|
||||
_onServerLog = StreamController<ServerLogParams>(sync: true);
|
||||
onServerLog = _onServerLog.stream.asBroadcastStream();
|
||||
_onServerStatus = StreamController<ServerStatusParams>(sync: true);
|
||||
onServerStatus = _onServerStatus.stream.asBroadcastStream();
|
||||
_onAnalysisAnalyzedFiles =
|
||||
StreamController<AnalysisAnalyzedFilesParams>(sync: true);
|
||||
onAnalysisAnalyzedFiles =
|
||||
_onAnalysisAnalyzedFiles.stream.asBroadcastStream();
|
||||
_onAnalysisClosingLabels =
|
||||
StreamController<AnalysisClosingLabelsParams>(sync: true);
|
||||
onAnalysisClosingLabels =
|
||||
_onAnalysisClosingLabels.stream.asBroadcastStream();
|
||||
_onAnalysisErrors = StreamController<AnalysisErrorsParams>(sync: true);
|
||||
onAnalysisErrors = _onAnalysisErrors.stream.asBroadcastStream();
|
||||
_onAnalysisFlushResults =
|
||||
StreamController<AnalysisFlushResultsParams>(sync: true);
|
||||
onAnalysisFlushResults = _onAnalysisFlushResults.stream.asBroadcastStream();
|
||||
_onAnalysisFolding = StreamController<AnalysisFoldingParams>(sync: true);
|
||||
onAnalysisFolding = _onAnalysisFolding.stream.asBroadcastStream();
|
||||
_onAnalysisHighlights =
|
||||
StreamController<AnalysisHighlightsParams>(sync: true);
|
||||
onAnalysisHighlights = _onAnalysisHighlights.stream.asBroadcastStream();
|
||||
_onAnalysisImplemented =
|
||||
StreamController<AnalysisImplementedParams>(sync: true);
|
||||
onAnalysisImplemented = _onAnalysisImplemented.stream.asBroadcastStream();
|
||||
_onAnalysisInvalidate =
|
||||
StreamController<AnalysisInvalidateParams>(sync: true);
|
||||
onAnalysisInvalidate = _onAnalysisInvalidate.stream.asBroadcastStream();
|
||||
_onAnalysisNavigation =
|
||||
StreamController<AnalysisNavigationParams>(sync: true);
|
||||
onAnalysisNavigation = _onAnalysisNavigation.stream.asBroadcastStream();
|
||||
_onAnalysisOccurrences =
|
||||
StreamController<AnalysisOccurrencesParams>(sync: true);
|
||||
onAnalysisOccurrences = _onAnalysisOccurrences.stream.asBroadcastStream();
|
||||
_onAnalysisOutline = StreamController<AnalysisOutlineParams>(sync: true);
|
||||
onAnalysisOutline = _onAnalysisOutline.stream.asBroadcastStream();
|
||||
_onAnalysisOverrides =
|
||||
StreamController<AnalysisOverridesParams>(sync: true);
|
||||
onAnalysisOverrides = _onAnalysisOverrides.stream.asBroadcastStream();
|
||||
_onCompletionResults =
|
||||
StreamController<CompletionResultsParams>(sync: true);
|
||||
onCompletionResults = _onCompletionResults.stream.asBroadcastStream();
|
||||
_onCompletionAvailableSuggestions =
|
||||
StreamController<CompletionAvailableSuggestionsParams>(sync: true);
|
||||
onCompletionAvailableSuggestions =
|
||||
_onCompletionAvailableSuggestions.stream.asBroadcastStream();
|
||||
_onCompletionExistingImports =
|
||||
StreamController<CompletionExistingImportsParams>(sync: true);
|
||||
onCompletionExistingImports =
|
||||
_onCompletionExistingImports.stream.asBroadcastStream();
|
||||
_onSearchResults = StreamController<SearchResultsParams>(sync: true);
|
||||
onSearchResults = _onSearchResults.stream.asBroadcastStream();
|
||||
_onExecutionLaunchData =
|
||||
StreamController<ExecutionLaunchDataParams>(sync: true);
|
||||
onExecutionLaunchData = _onExecutionLaunchData.stream.asBroadcastStream();
|
||||
_onFlutterOutline = StreamController<FlutterOutlineParams>(sync: true);
|
||||
onFlutterOutline = _onFlutterOutline.stream.asBroadcastStream();
|
||||
}
|
||||
final _onFlutterOutline = StreamController<FlutterOutlineParams>(sync: true);
|
||||
|
||||
/// Dispatch the notification named [event], and containing parameters
|
||||
/// [params], to the appropriate stream.
|
||||
|
||||
@@ -79,8 +79,7 @@ typedef MismatchDescriber = Description Function(
|
||||
typedef NotificationProcessor = void Function(String event, Map params);
|
||||
|
||||
/// Base class for analysis server integration tests.
|
||||
abstract class AbstractAnalysisServerIntegrationTest
|
||||
extends IntegrationTestMixin {
|
||||
abstract class AbstractAnalysisServerIntegrationTest extends IntegrationTest {
|
||||
/// Amount of time to give the server to respond to a shutdown request before
|
||||
/// forcibly terminating it.
|
||||
static const Duration SHUTDOWN_TIMEOUT = Duration(seconds: 60);
|
||||
@@ -110,10 +109,6 @@ abstract class AbstractAnalysisServerIntegrationTest
|
||||
|
||||
String dartSdkPath = path.dirname(path.dirname(Platform.resolvedExecutable));
|
||||
|
||||
AbstractAnalysisServerIntegrationTest() {
|
||||
initializeInttestMixin();
|
||||
}
|
||||
|
||||
/// Return a future which will complete when a 'server.status' notification is
|
||||
/// received from the server with 'analyzing' set to false.
|
||||
///
|
||||
@@ -609,7 +604,7 @@ class Server {
|
||||
/// Start the server. If [profileServer] is `true`, the server will be started
|
||||
/// with "--observe" and "--pause-isolates-on-exit", allowing the observatory
|
||||
/// to be used.
|
||||
Future start({
|
||||
Future<void> start({
|
||||
required String dartSdkPath,
|
||||
int? diagnosticPort,
|
||||
String? instrumentationLogFile,
|
||||
|
||||
@@ -96,7 +96,7 @@ class TimingResult {
|
||||
|
||||
/// The abstract class [TimingTest] defines the behavior of objects that measure
|
||||
/// the time required to perform some sequence of server operations.
|
||||
abstract class TimingTest extends IntegrationTestMixin {
|
||||
abstract class TimingTest extends IntegrationTest {
|
||||
/// The number of times the test will be performed in order to warm up the VM.
|
||||
static final int DEFAULT_WARMUP_COUNT = 10;
|
||||
|
||||
@@ -125,9 +125,6 @@ abstract class TimingTest extends IntegrationTestMixin {
|
||||
/// shutdown.
|
||||
bool skipShutdown = false;
|
||||
|
||||
/// Initialize a newly created test.
|
||||
TimingTest();
|
||||
|
||||
/// Return the number of iterations that should be performed in order to
|
||||
/// compute a time.
|
||||
int get timingCount => DEFAULT_TIMING_COUNT;
|
||||
@@ -138,11 +135,10 @@ abstract class TimingTest extends IntegrationTestMixin {
|
||||
|
||||
/// Perform any operations that need to be performed once before any
|
||||
/// iterations.
|
||||
Future oneTimeSetUp() {
|
||||
initializeInttestMixin();
|
||||
Future<void> oneTimeSetUp() {
|
||||
server = Server();
|
||||
sourceDirectory = Directory.systemTemp.createTempSync('analysisServer');
|
||||
var serverConnected = Completer();
|
||||
var serverConnected = Completer<void>();
|
||||
onServerConnected.listen((_) {
|
||||
serverConnected.complete();
|
||||
});
|
||||
@@ -159,7 +155,7 @@ abstract class TimingTest extends IntegrationTestMixin {
|
||||
|
||||
/// Perform any operations that need to be performed once after all
|
||||
/// iterations.
|
||||
Future oneTimeTearDown() {
|
||||
Future<void> oneTimeTearDown() {
|
||||
return _shutdownIfNeeded().then((_) {
|
||||
sourceDirectory.deleteSync(recursive: true);
|
||||
});
|
||||
@@ -213,7 +209,7 @@ abstract class TimingTest extends IntegrationTestMixin {
|
||||
|
||||
/// Repeatedly execute this test [count] times, adding timing information to
|
||||
/// the given list of [times] if it is non-`null`.
|
||||
Future _repeat(int count, List<int>? times) {
|
||||
Future<void> _repeat(int count, List<int>? times) {
|
||||
var stopwatch = Stopwatch();
|
||||
return setUp().then((_) {
|
||||
stopwatch.start();
|
||||
@@ -234,7 +230,7 @@ abstract class TimingTest extends IntegrationTestMixin {
|
||||
}
|
||||
|
||||
/// Shut the server down unless [skipShutdown] is `true`.
|
||||
Future _shutdownIfNeeded() {
|
||||
Future<void> _shutdownIfNeeded() {
|
||||
if (skipShutdown) {
|
||||
return Future.value();
|
||||
}
|
||||
|
||||
@@ -90,32 +90,22 @@ class CodegenInttestMethodsVisitor extends DartCodegenVisitor
|
||||
writeln("import 'package:$packageName/protocol/protocol_generated.dart';");
|
||||
writeln(
|
||||
"import 'package:$packageName/src/protocol/protocol_internal.dart';");
|
||||
writeln("import 'package:test/test.dart';");
|
||||
writeln();
|
||||
writeln("import 'integration_tests.dart';");
|
||||
writeln("import 'protocol_matchers.dart';");
|
||||
for (var uri in api.types.importUris) {
|
||||
write("import '");
|
||||
write(uri);
|
||||
writeln("';");
|
||||
}
|
||||
writeln("import 'package:test/test.dart';");
|
||||
writeln();
|
||||
writeln('/// Convenience methods for running integration tests.');
|
||||
writeln('abstract class IntegrationTestMixin {');
|
||||
writeln("import 'integration_tests.dart';");
|
||||
writeln("import 'protocol_matchers.dart';");
|
||||
writeln();
|
||||
writeln('/// Base implementation for running integration tests.');
|
||||
writeln('abstract class IntegrationTest {');
|
||||
indent(() {
|
||||
writeln('Server get server;');
|
||||
super.visitApi();
|
||||
writeln();
|
||||
docComment(toHtmlVisitor.collectHtml(() {
|
||||
toHtmlVisitor.writeln('Initialize the fields in InttestMixin, and');
|
||||
toHtmlVisitor.writeln('ensure that notifications will be handled.');
|
||||
}));
|
||||
writeln('void initializeInttestMixin() {');
|
||||
indent(() {
|
||||
write(fieldInitializationCode.join());
|
||||
});
|
||||
writeln('}');
|
||||
writeln();
|
||||
docComment(toHtmlVisitor.collectHtml(() {
|
||||
toHtmlVisitor.writeln('Dispatch the notification named [event], and');
|
||||
toHtmlVisitor.writeln('containing parameters [params], to the');
|
||||
@@ -151,16 +141,13 @@ class CodegenInttestMethodsVisitor extends DartCodegenVisitor
|
||||
toHtmlVisitor.translateHtml(notification.html);
|
||||
toHtmlVisitor.describePayload(notification.params, 'Parameters');
|
||||
}));
|
||||
writeln('late Stream<$className> $streamName;');
|
||||
writeln('late final Stream<$className> $streamName = '
|
||||
'_$streamName.stream.asBroadcastStream();');
|
||||
writeln();
|
||||
docComment(toHtmlVisitor.collectHtml(() {
|
||||
toHtmlVisitor.write('Stream controller for [$streamName].');
|
||||
}));
|
||||
writeln('late StreamController<$className> _$streamName;');
|
||||
fieldInitializationCode.add(collectCode(() {
|
||||
writeln('_$streamName = StreamController<$className>(sync: true);');
|
||||
writeln('$streamName = _$streamName.stream.asBroadcastStream();');
|
||||
}));
|
||||
writeln('final _$streamName = StreamController<$className>(sync: true);');
|
||||
notificationSwitchContents.add(collectCode(() {
|
||||
writeln("case '${notification.longEvent}':");
|
||||
indent(() {
|
||||
@@ -215,7 +202,7 @@ class CodegenInttestMethodsVisitor extends DartCodegenVisitor
|
||||
doCapitalize: true);
|
||||
futureClass = 'Future<$resultClass>';
|
||||
} else {
|
||||
futureClass = 'Future';
|
||||
futureClass = 'Future<void>';
|
||||
}
|
||||
|
||||
writeln('$futureClass $methodName(${args.join(', ')}) async {');
|
||||
@@ -249,7 +236,6 @@ class CodegenInttestMethodsVisitor extends DartCodegenVisitor
|
||||
writeln("return $resultClass.fromJson(decoder, 'result', result);");
|
||||
} else {
|
||||
writeln('outOfTestExpect(result, isNull);');
|
||||
writeln('return null;');
|
||||
}
|
||||
});
|
||||
writeln('}');
|
||||
|
||||
Reference in New Issue
Block a user