Version 2.10.0-131.0.dev

Merge commit 'f7d1c55a1919354e8c54486144f428a71b2f6bab' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
index 8455340..55986c9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
@@ -16,27 +16,28 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var conditional = node.thisOrAncestorOfType<ConditionalExpression>();
-    if (conditional == null) {
-      return;
-    }
-    var condition = conditional.condition as BinaryExpression;
-    Expression nullableExpression;
-    Expression defaultExpression;
-    if (condition.operator.type == TokenType.EQ_EQ) {
-      nullableExpression = conditional.elseExpression;
-      defaultExpression = conditional.thenExpression;
-    } else {
-      nullableExpression = conditional.thenExpression;
-      defaultExpression = conditional.elseExpression;
-    }
-    await builder.addDartFileEdit(file, (builder) {
-      builder.addReplacement(range.node(conditional), (builder) {
-        builder.write(utils.getNodeText(nullableExpression));
-        builder.write(' ?? ');
-        builder.write(utils.getNodeText(defaultExpression));
+    var node = this.node;
+    if (node is ConditionalExpression &&
+        node.offset == errorOffset &&
+        node.length == errorLength) {
+      var condition = node.condition as BinaryExpression;
+      Expression nullableExpression;
+      Expression defaultExpression;
+      if (condition.operator.type == TokenType.EQ_EQ) {
+        nullableExpression = node.elseExpression;
+        defaultExpression = node.thenExpression;
+      } else {
+        nullableExpression = node.thenExpression;
+        defaultExpression = node.elseExpression;
+      }
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addReplacement(range.node(node), (builder) {
+          builder.write(utils.getNodeText(nullableExpression));
+          builder.write(' ?? ');
+          builder.write(utils.getNodeText(defaultExpression));
+        });
       });
-    });
+    }
   }
 
   /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index 4e79f93..e69a2bc 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -5,7 +5,6 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/channel/lsp_byte_stream_channel.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -25,24 +24,17 @@
   /// Sends a request to the server and unwraps the result. Throws if the
   /// response was not successful or returned an error.
   @override
-  Future<T> expectSuccessfulResponseTo<T>(RequestMessage request) async {
+  Future<T> expectSuccessfulResponseTo<T, R>(
+      RequestMessage request, T Function(R) fromJson) async {
     final resp = await sendRequestToServer(request);
     if (resp.error != null) {
       throw resp.error;
-      // TODO(dantup): It would be better if we had some code-gen'd way
-      // to be able to deserialise into the correct types. We could either
-      // code-gen this list, or code-gen the LSP client (used in tests) to
-      // give strongly typed sendXxx functions that return the correct types.
-    } else if (T == DartDiagnosticServer) {
-      return DartDiagnosticServer.fromJson(resp.result) as T;
     } else if (T == Null) {
       return resp.result == null
           ? null
           : throw 'Expected Null response but got ${resp.result}';
     } else {
-      throw 'Unable to deserialise ${resp.result.runtimeType} into $T.\n\n'
-          'You may need to extend expectSuccessfulResponseTo in '
-          'AbstractLspAnalysisServerIntegrationTest';
+      return fromJson(resp.result);
     }
   }
 
diff --git a/pkg/analysis_server/test/lsp/code_actions_abstract.dart b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
index 5c3cd8c..33f1418 100644
--- a/pkg/analysis_server/test/lsp/code_actions_abstract.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
@@ -100,6 +100,7 @@
     final commandResponse = await handleExpectedRequest<Object,
         ApplyWorkspaceEditParams, ApplyWorkspaceEditResponse>(
       Method.workspace_applyEdit,
+      ApplyWorkspaceEditParams.fromJson,
       () => executeCommand(command),
       handler: (edit) {
         // When the server sends the edit back, just keep a copy and say we
diff --git a/pkg/analysis_server/test/lsp/code_actions_source_test.dart b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
index 1c15d8b..8f4e841 100644
--- a/pkg/analysis_server/test/lsp/code_actions_source_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
@@ -277,6 +277,7 @@
     final commandResponse = handleExpectedRequest<Object,
         ApplyWorkspaceEditParams, ApplyWorkspaceEditResponse>(
       Method.workspace_applyEdit,
+      ApplyWorkspaceEditParams.fromJson,
       () => executeCommand(command),
       // Claim that we failed tpo apply the edits. This is what the client
       // would do if the edits provided were for an old version of the
diff --git a/pkg/analysis_server/test/lsp/completion_test.dart b/pkg/analysis_server/test/lsp/completion_test.dart
index 478aaf0..07446e9 100644
--- a/pkg/analysis_server/test/lsp/completion_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_test.dart
@@ -53,7 +53,7 @@
 
     // By default, there should be no commit characters.
     var reg = registration(Method.textDocument_completion);
-    var options = reg.registerOptions as CompletionRegistrationOptions;
+    var options = CompletionRegistrationOptions.fromJson(reg.registerOptions);
     expect(options.allCommitCharacters, isNull);
 
     // When we change config, we should get a re-registration (unregister then
@@ -61,7 +61,7 @@
     await monitorDynamicReregistration(
         registrations, () => updateConfig({'previewCommitCharacters': true}));
     reg = registration(Method.textDocument_completion);
-    options = reg.registerOptions as CompletionRegistrationOptions;
+    options = CompletionRegistrationOptions.fromJson(reg.registerOptions);
     expect(options.allCommitCharacters, equals(dartCompletionCommitCharacters));
   }
 
@@ -935,6 +935,7 @@
     final commandResponse = await handleExpectedRequest<Object,
         ApplyWorkspaceEditParams, ApplyWorkspaceEditResponse>(
       Method.workspace_applyEdit,
+      ApplyWorkspaceEditParams.fromJson,
       () => executeCommand(resolved.command),
       handler: (edit) {
         // When the server sends the edit back, just keep a copy and say we
diff --git a/pkg/analysis_server/test/lsp/document_symbols_test.dart b/pkg/analysis_server/test/lsp/document_symbols_test.dart
index e571578..f66964d 100644
--- a/pkg/analysis_server/test/lsp/document_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/document_symbols_test.dart
@@ -154,8 +154,10 @@
     await initialize();
 
     final result = await getDocumentSymbols(pubspecFileUri.toString());
+    // Since the list is empty, it will deserialise into whatever the first
+    // type is, so just accept both types.
     final symbols = result.map(
-      (docsymbols) => throw 'Expected SymbolInformations, got DocumentSymbols',
+      (docsymbols) => docsymbols,
       (symbolInfos) => symbolInfos,
     );
     expect(symbols, isEmpty);
diff --git a/pkg/analysis_server/test/lsp/file_modification_test.dart b/pkg/analysis_server/test/lsp/file_modification_test.dart
index 9afc443..3c9dac5 100644
--- a/pkg/analysis_server/test/lsp/file_modification_test.dart
+++ b/pkg/analysis_server/test/lsp/file_modification_test.dart
@@ -25,7 +25,7 @@
     // Since this is a notification and not a request, the server cannot
     // respond with an error, but instead sends a ShowMessage notification
     // to alert the user to something failing.
-    final error = await expectErrorNotification<ShowMessageParams>(() async {
+    final error = await expectErrorNotification(() async {
       await changeFile(222, mainFileUri, [
         Either2<TextDocumentContentChangeEvent1,
             TextDocumentContentChangeEvent2>.t1(TextDocumentContentChangeEvent1(
@@ -87,7 +87,7 @@
       text: 'test',
     ));
     await initialize();
-    final notificationParams = await expectErrorNotification<ShowMessageParams>(
+    final notificationParams = await expectErrorNotification(
       () => changeFile(222, mainFileUri, [simpleEdit]),
     );
     expect(notificationParams, isNotNull);
@@ -133,7 +133,7 @@
   Future<void> test_open_invalidPath() async {
     await initialize();
 
-    final notificationParams = await expectErrorNotification<ShowMessageParams>(
+    final notificationParams = await expectErrorNotification(
       () => openFile(Uri.http('localhost', 'not-a-file'), ''),
     );
     expect(notificationParams, isNotNull);
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 72596b7..eeebebb 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/json_parsing.dart';
 import 'package:analysis_server/src/lsp/server_capabilities_computer.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:path/path.dart' as path;
@@ -25,7 +26,8 @@
     List<Registration> registrations,
     Method method,
   ) {
-    return registrationFor(registrations, method)?.registerOptions;
+    return TextDocumentRegistrationOptions.fromJson(
+        registrationFor(registrations, method)?.registerOptions);
   }
 
   Future<void> test_dynamicRegistration_containsAppropriateSettings() async {
@@ -45,7 +47,7 @@
     // Because we support dynamic registration for synchronisation, we won't send
     // static registrations for them.
     // https://github.com/dart-lang/sdk/issues/38490
-    InitializeResult initResult = initResponse.result;
+    final initResult = InitializeResult.fromJson(initResponse.result);
     expect(initResult.serverInfo.name, 'Dart SDK LSP Analysis Server');
     expect(initResult.serverInfo.version, isNotNull);
     expect(initResult.capabilities, isNotNull);
@@ -95,7 +97,7 @@
     final initResponse = await initialize();
     await pumpEventQueue();
 
-    InitializeResult initResult = initResponse.result;
+    final initResult = InitializeResult.fromJson(initResponse.result);
     expect(initResult.capabilities, isNotNull);
     // When dynamic registration is not supported, we will always statically
     // request text document open/close and incremental updates.
@@ -151,7 +153,7 @@
               emptyTextDocumentClientCapabilities)),
     );
 
-    InitializeResult initResult = initResponse.result;
+    final initResult = InitializeResult.fromJson(initResponse.result);
     expect(initResult.capabilities, isNotNull);
 
     // Ensure no static registrations. This list should include all server equivilents
@@ -196,7 +198,8 @@
       pluginManager.pluginsChangedController.add(null);
     });
     final unregistrations =
-        (unregisterRequest.params as UnregistrationParams).unregisterations;
+        UnregistrationParams.fromJson(unregisterRequest.params)
+            .unregisterations;
 
     // folding method should have been unregistered as the server now supports
     // *.foo files for it as well.
@@ -226,7 +229,7 @@
         .firstWhere((r) => r.method == Method.client_unregisterCapability)
         .then((request) {
       respondTo(request, null);
-      return (request.params as UnregistrationParams).unregisterations;
+      return UnregistrationParams.fromJson(request.params).unregisterations;
     });
 
     final request = await expectRequest(Method.client_registerCapability, () {
@@ -236,24 +239,23 @@
       pluginManager.pluginsChangedController.add(null);
     });
 
-    final registrations = (request.params as RegistrationParams).registrations;
+    final registrations =
+        RegistrationParams.fromJson(request.params).registrations;
 
     final documentFilterSql =
         DocumentFilter(scheme: 'file', pattern: '**/*.sql');
     final documentFilterDart = DocumentFilter(language: 'dart', scheme: 'file');
-    final expectedFoldingRegistration =
-        isA<TextDocumentRegistrationOptions>().having(
-      (o) => o.documentSelector,
-      'documentSelector',
-      containsAll([documentFilterSql, documentFilterDart]),
-    );
 
     expect(
       registrations,
       contains(isA<Registration>()
           .having((r) => r.method, 'method', 'textDocument/foldingRange')
-          .having((r) => r.registerOptions, 'registerOptions',
-              expectedFoldingRegistration)),
+          .having(
+            (r) => TextDocumentRegistrationOptions.fromJson(r.registerOptions)
+                .documentSelector,
+            'registerOptions.documentSelector',
+            containsAll([documentFilterSql, documentFilterDart]),
+          )),
     );
   }
 
@@ -334,8 +336,9 @@
     expect(response, isNotNull);
     expect(response.error, isNull);
     expect(response.result, isNotNull);
-    expect(response.result, TypeMatcher<InitializeResult>());
-    InitializeResult result = response.result;
+    expect(InitializeResult.canParse(response.result, nullLspJsonReporter),
+        isTrue);
+    final result = InitializeResult.fromJson(response.result);
     expect(result.capabilities, isNotNull);
     // Check some basic capabilities that are unlikely to change.
     expect(result.capabilities.textDocumentSync, isNotNull);
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index f7ec998..271c2c6 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/json_parsing.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
@@ -77,12 +78,13 @@
   /// Sends a request to the server and unwraps the result. Throws if the
   /// response was not successful or returned an error.
   @override
-  Future<T> expectSuccessfulResponseTo<T>(RequestMessage request) async {
+  Future<T> expectSuccessfulResponseTo<T, R>(
+      RequestMessage request, T Function(R) fromJson) async {
     final resp = await sendRequestToServer(request);
     if (resp.error != null) {
       throw resp.error;
     } else {
-      return resp.result as T;
+      return resp.result == null ? null : fromJson(resp.result);
     }
   }
 
@@ -575,7 +577,7 @@
         arguments: command.arguments,
       ),
     );
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(request, (result) => result);
   }
 
   void expectDocumentVersion(
@@ -617,7 +619,7 @@
     );
   }
 
-  Future<T> expectErrorNotification<T>(
+  Future<ShowMessageParams> expectErrorNotification(
     FutureOr<void> Function() f, {
     Duration timeout = const Duration(seconds: 5),
   }) async {
@@ -627,7 +629,7 @@
     final notificationFromServer = await firstError.timeout(timeout);
 
     expect(notificationFromServer, isNotNull);
-    return notificationFromServer.params as T;
+    return ShowMessageParams.fromJson(notificationFromServer.params);
   }
 
   Future<T> expectNotification<T>(
@@ -660,7 +662,8 @@
     return requestFromServer;
   }
 
-  Future<T> expectSuccessfulResponseTo<T>(RequestMessage request);
+  Future<T> expectSuccessfulResponseTo<T, R>(
+      RequestMessage request, T Function(R) fromJson);
 
   Future<List<TextEdit>> formatDocument(String fileUri) {
     final request = makeRequest(
@@ -672,7 +675,8 @@
             insertSpaces: true), // These currently don't do anything
       ),
     );
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(TextEdit.fromJson));
   }
 
   Future<List<TextEdit>> formatOnType(
@@ -688,7 +692,8 @@
         position: pos,
       ),
     );
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(TextEdit.fromJson));
   }
 
   Future<List<Either2<Command, CodeAction>>> getCodeActions(
@@ -707,7 +712,11 @@
         context: CodeActionContext(diagnostics: [], only: kinds),
       ),
     );
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(
+      request,
+      _fromJsonList(_generateFromJsonFor(Command.canParse, Command.fromJson,
+          CodeAction.canParse, CodeAction.fromJson)),
+    );
   }
 
   Future<List<CompletionItem>> getCompletion(Uri uri, Position pos,
@@ -720,7 +729,8 @@
         position: pos,
       ),
     );
-    return expectSuccessfulResponseTo<List<CompletionItem>>(request);
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(CompletionItem.fromJson));
   }
 
   Future<Either2<List<Location>, List<LocationLink>>> getDefinition(
@@ -732,7 +742,14 @@
         position: pos,
       ),
     );
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(
+      request,
+      _generateFromJsonFor(
+          _canParseList(Location.canParse),
+          _fromJsonList(Location.fromJson),
+          _canParseList(LocationLink.canParse),
+          _fromJsonList(LocationLink.fromJson)),
+    );
   }
 
   Future<List<Location>> getDefinitionAsLocation(Uri uri, Position pos) async {
@@ -757,7 +774,7 @@
       CustomMethods.DiagnosticServer,
       null,
     );
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(request, DartDiagnosticServer.fromJson);
   }
 
   Future<List<DocumentHighlight>> getDocumentHighlights(Uri uri, Position pos) {
@@ -768,7 +785,8 @@
         position: pos,
       ),
     );
-    return expectSuccessfulResponseTo<List<DocumentHighlight>>(request);
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(DocumentHighlight.fromJson));
   }
 
   Future<Either2<List<DocumentSymbol>, List<SymbolInformation>>>
@@ -779,7 +797,14 @@
         textDocument: TextDocumentIdentifier(uri: fileUri),
       ),
     );
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(
+      request,
+      _generateFromJsonFor(
+          _canParseList(DocumentSymbol.canParse),
+          _fromJsonList(DocumentSymbol.fromJson),
+          _canParseList(SymbolInformation.canParse),
+          _fromJsonList(SymbolInformation.fromJson)),
+    );
   }
 
   Future<List<FoldingRange>> getFoldingRegions(Uri uri) {
@@ -789,7 +814,8 @@
         textDocument: TextDocumentIdentifier(uri: uri.toString()),
       ),
     );
-    return expectSuccessfulResponseTo<List<FoldingRange>>(request);
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(FoldingRange.fromJson));
   }
 
   Future<Hover> getHover(Uri uri, Position pos) {
@@ -799,7 +825,7 @@
           textDocument: TextDocumentIdentifier(uri: uri.toString()),
           position: pos),
     );
-    return expectSuccessfulResponseTo<Hover>(request);
+    return expectSuccessfulResponseTo(request, Hover.fromJson);
   }
 
   Future<List<Location>> getImplementations(
@@ -814,7 +840,8 @@
         position: pos,
       ),
     );
-    return expectSuccessfulResponseTo<List<Location>>(request);
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(Location.fromJson));
   }
 
   Future<List<Location>> getReferences(
@@ -830,7 +857,8 @@
         position: pos,
       ),
     );
-    return expectSuccessfulResponseTo<List<Location>>(request);
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(Location.fromJson));
   }
 
   Future<SignatureHelp> getSignatureHelp(Uri uri, Position pos,
@@ -843,7 +871,7 @@
         context: context,
       ),
     );
-    return expectSuccessfulResponseTo<SignatureHelp>(request);
+    return expectSuccessfulResponseTo(request, SignatureHelp.fromJson);
   }
 
   Future<Location> getSuper(
@@ -857,7 +885,7 @@
         position: pos,
       ),
     );
-    return expectSuccessfulResponseTo<Location>(request);
+    return expectSuccessfulResponseTo(request, Location.fromJson);
   }
 
   Future<List<SymbolInformation>> getWorkspaceSymbols(String query) {
@@ -865,7 +893,8 @@
       Method.workspace_symbol,
       WorkspaceSymbolParams(query: query),
     );
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(SymbolInformation.fromJson));
   }
 
   /// Executes [f] then waits for a request of type [method] from the server which
@@ -889,6 +918,7 @@
   /// response to the request it sends (3).
   Future<T> handleExpectedRequest<T, R, RR>(
     Method method,
+    R Function(Map<String, dynamic>) fromJson,
     Future<T> Function() f, {
     @required FutureOr<RR> Function(R) handler,
     Duration timeout = const Duration(seconds: 5),
@@ -903,7 +933,7 @@
     });
 
     // Handle the request from the server and send the response back.
-    final clientsResponse = await handler(incomingRequest.params as R);
+    final clientsResponse = await handler(fromJson(incomingRequest.params));
     respondTo(incomingRequest, clientsResponse);
 
     // Return a future that completes when the response to the original request
@@ -996,6 +1026,7 @@
   ) {
     return handleExpectedRequest<ResponseMessage, RegistrationParams, void>(
       Method.client_registerCapability,
+      RegistrationParams.fromJson,
       f,
       handler: (registrationParams) {
         registrations.addAll(registrationParams.registrations);
@@ -1021,6 +1052,7 @@
   ) {
     return handleExpectedRequest<ResponseMessage, UnregistrationParams, void>(
       Method.client_unregisterCapability,
+      UnregistrationParams.fromJson,
       f,
       handler: (unregistrationParams) {
         registrations.removeWhere((element) => unregistrationParams
@@ -1070,7 +1102,7 @@
         position: pos,
       ),
     );
-    return expectSuccessfulResponseTo<RangeAndPlaceholder>(request);
+    return expectSuccessfulResponseTo(request, RangeAndPlaceholder.fromJson);
   }
 
   /// Calls the supplied function and responds to any `workspace/configuration`
@@ -1080,6 +1112,7 @@
     return handleExpectedRequest<ResponseMessage, ConfigurationParams,
         List<Map<String, dynamic>>>(
       Method.workspace_configuration,
+      ConfigurationParams.fromJson,
       f,
       handler: (configurationParams) async => [await config],
     );
@@ -1155,7 +1188,7 @@
     String newName,
   ) {
     final request = makeRenameRequest(version, uri, pos, newName);
-    return expectSuccessfulResponseTo<WorkspaceEdit>(request);
+    return expectSuccessfulResponseTo(request, WorkspaceEdit.fromJson);
   }
 
   Future<ResponseMessage> renameRaw(
@@ -1185,7 +1218,7 @@
       Method.completionItem_resolve,
       item,
     );
-    return expectSuccessfulResponseTo<CompletionItem>(request);
+    return expectSuccessfulResponseTo(request, CompletionItem.fromJson);
   }
 
   /// Sends [responseParams] to the server as a successful response to
@@ -1216,7 +1249,7 @@
 
   Future<Null> sendShutdown() {
     final request = makeRequest(Method.shutdown, null);
-    return expectSuccessfulResponseTo(request);
+    return expectSuccessfulResponseTo(request, (result) => result);
   }
 
   WorkspaceFolder toWorkspaceFolder(Uri uri) {
@@ -1246,7 +1279,7 @@
     await serverToClient.firstWhere((message) {
       if (message is NotificationMessage &&
           message.method == CustomMethods.AnalyzerStatus) {
-        params = _convertParams(message, AnalyzerStatusParams.fromJson);
+        params = AnalyzerStatusParams.fromJson(message.params);
         return params.isAnalyzing == analyzing;
       }
       return false;
@@ -1260,7 +1293,7 @@
       if (message is NotificationMessage &&
           message.method == CustomMethods.PublishClosingLabels) {
         closingLabelsParams =
-            _convertParams(message, PublishClosingLabelsParams.fromJson);
+            PublishClosingLabelsParams.fromJson(message.params);
 
         return closingLabelsParams.uri == uri.toString();
       }
@@ -1274,8 +1307,7 @@
     await serverToClient.firstWhere((message) {
       if (message is NotificationMessage &&
           message.method == Method.textDocument_publishDiagnostics) {
-        diagnosticParams =
-            _convertParams(message, PublishDiagnosticsParams.fromJson);
+        diagnosticParams = PublishDiagnosticsParams.fromJson(message.params);
         return diagnosticParams.uri == uri.toString();
       }
       return false;
@@ -1288,8 +1320,7 @@
     await serverToClient.firstWhere((message) {
       if (message is NotificationMessage &&
           message.method == CustomMethods.PublishFlutterOutline) {
-        outlineParams =
-            _convertParams(message, PublishFlutterOutlineParams.fromJson);
+        outlineParams = PublishFlutterOutlineParams.fromJson(message.params);
 
         return outlineParams.uri == uri.toString();
       }
@@ -1303,7 +1334,7 @@
     await serverToClient.firstWhere((message) {
       if (message is NotificationMessage &&
           message.method == CustomMethods.PublishOutline) {
-        outlineParams = _convertParams(message, PublishOutlineParams.fromJson);
+        outlineParams = PublishOutlineParams.fromJson(message.params);
 
         return outlineParams.uri == uri.toString();
       }
@@ -1321,15 +1352,15 @@
   String withoutRangeMarkers(String contents) =>
       contents.replaceAll(rangeMarkerStart, '').replaceAll(rangeMarkerEnd, '');
 
-  /// A helper to simplify processing of results for both in-process tests (where
-  /// we'll get the real type back), and out-of-process integration tests (where
-  /// params is `Map<String, dynamic>` and needs to be fromJson'd).
-  T _convertParams<T>(
-    IncomingMessage message,
-    T Function(Map<String, dynamic>) fromJson,
-  ) {
-    return message.params is T ? message.params : fromJson(message.params);
-  }
+  bool Function(List<dynamic>, LspJsonReporter) _canParseList<T>(
+          bool Function(Map<String, dynamic>, LspJsonReporter) canParse) =>
+      (input, reporter) => input
+          .cast<Map<String, dynamic>>()
+          .every((item) => canParse(item, reporter));
+
+  List<T> Function(List<dynamic>) _fromJsonList<T>(
+          T Function(Map<String, dynamic>) fromJson) =>
+      (input) => input.cast<Map<String, dynamic>>().map(fromJson).toList();
 
   /// Checks whether a notification is likely an error from the server (for
   /// example a window/showMessage). This is useful for tests that want to
@@ -1339,4 +1370,24 @@
     return notification.method == Method.window_logMessage ||
         notification.method == Method.window_showMessage;
   }
+
+  /// Creates a `fromJson()` function for an `Either2<T1, T2>` using
+  /// the `canParse` and `fromJson` functions for each type.
+  static Either2<T1, T2> Function(R) _generateFromJsonFor<T1, T2, R>(
+      bool Function(R, LspJsonReporter) canParse1,
+      T1 Function(R) fromJson1,
+      bool Function(R, LspJsonReporter) canParse2,
+      T2 Function(R) fromJson2,
+      [LspJsonReporter reporter]) {
+    reporter ??= nullLspJsonReporter;
+    return (input) {
+      if (canParse1(input, reporter)) {
+        return Either2<T1, T2>.t1(fromJson1(input));
+      }
+      if (canParse2(input, reporter)) {
+        return Either2<T1, T2>.t2(fromJson2(input));
+      }
+      throw '$input was not one of ($T1, $T2)';
+    };
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/server_test.dart b/pkg/analysis_server/test/lsp/server_test.dart
index 3e7a202..8b0bd596 100644
--- a/pkg/analysis_server/test/lsp/server_test.dart
+++ b/pkg/analysis_server/test/lsp/server_test.dart
@@ -22,7 +22,7 @@
     await openFile(mainFileUri, '');
     // Attempt to make an illegal modification to the file. This indicates the
     // client and server are out of sync and we expect the server to shut down.
-    final error = await expectErrorNotification<ShowMessageParams>(() async {
+    final error = await expectErrorNotification(() async {
       await changeFile(222, mainFileUri, [
         Either2<TextDocumentContentChangeEvent1,
                 TextDocumentContentChangeEvent2>.t1(
@@ -58,7 +58,7 @@
     final notification =
         makeNotification(Method.fromJson(r'some/randomNotification'), null);
 
-    final notificationParams = await expectErrorNotification<ShowMessageParams>(
+    final notificationParams = await expectErrorNotification(
       () => channel.sendNotificationToServer(notification),
     );
     expect(notificationParams, isNotNull);
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 11ad43c..56e583f 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -8,7 +8,6 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart' as lsp;
-import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
@@ -83,13 +82,6 @@
     }
   }
 
-  /// Run the object through JSON serialisation to catch any
-  /// issues like fields that are unserialisable types. This is used for
-  /// messages going server-to-client.
-  void ensureMessageCanBeJsonSerialized(ToJsonable message) {
-    jsonEncode(message.toJson());
-  }
-
   @override
   void listen(void Function(lsp.Message message) onMessage,
       {Function onError, void Function() onDone}) {
@@ -103,7 +95,7 @@
       return;
     }
 
-    ensureMessageCanBeJsonSerialized(notification);
+    notification = _convertJson(notification, lsp.NotificationMessage.fromJson);
 
     _serverToClient.add(notification);
   }
@@ -127,7 +119,7 @@
       return;
     }
 
-    ensureMessageCanBeJsonSerialized(request);
+    request = _convertJson(request, lsp.RequestMessage.fromJson);
 
     _serverToClient.add(request);
   }
@@ -155,7 +147,7 @@
       return;
     }
 
-    ensureMessageCanBeJsonSerialized(response);
+    response = _convertJson(response, lsp.ResponseMessage.fromJson);
 
     // Wrap send response in future to simulate WebSocket.
     Future(() => _serverToClient.add(response));
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
index ba18148..81c4960 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer/src/dart/error/lint_codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -36,6 +37,33 @@
 ''');
   }
 
+  Future<void> test_malformed() async {
+    await resolveTestUnit('''
+void f(String s, bool b) {
+  print(b ? s != null ? s : : null);
+}
+''');
+    await assertNoFix(errorFilter: (error) {
+      var code = error.errorCode;
+      return code is LintCode &&
+          code.name == LintNames.prefer_if_null_operators;
+    });
+  }
+
+  Future<void> test_malformed_parentheses() async {
+    // https://github.com/dart-lang/sdk/issues/43432
+    await resolveTestUnit('''
+void f(String s, bool b) {
+  print(b ? (s != null ? s : ) : null);
+}
+''');
+    await assertNoFix(errorFilter: (error) {
+      var code = error.errorCode;
+      return code is LintCode &&
+          code.name == LintNames.prefer_if_null_operators;
+    });
+  }
+
   Future<void> test_notEqual() async {
     await resolveTestUnit('''
 void f(String s) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 77e033b..e8c0531 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -414,16 +414,6 @@
 
   void _resolveReceiverInterfaceType(MethodInvocation node, Expression receiver,
       InterfaceType receiverType, SimpleIdentifier nameNode, String name) {
-    if (_isCoreFunction(receiverType) &&
-        name == FunctionElement.CALL_METHOD_NAME) {
-      _resolver.nullableDereferenceVerifier.expression(
-        receiver,
-        type: receiverType,
-      );
-      _setDynamicResolution(node);
-      return;
-    }
-
     _resolveReceiverType(
       node: node,
       receiver: receiver,
diff --git a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
index fd6587a..db73a0c 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -177,36 +177,21 @@
       nameErrorEntity: propertyName,
     );
 
-    if (targetType is DynamicTypeImpl || targetType is NeverTypeImpl) {
-      // OK
-    } else {
-      // TODO(scheglov) It is not nice that we check for `call` here.
-      // We can find `call` in these types, is should be `single`, but `null`.
-      if (hasRead && result.getter == null && !result.isAmbiguous) {
-        if (targetType is FunctionType &&
-            propertyName.name == FunctionElement.CALL_METHOD_NAME) {
-          // Referencing `.call` on a FunctionType is OK.
-        } else if (targetType is InterfaceType &&
-            targetType.isDartCoreFunction &&
-            propertyName.name == FunctionElement.CALL_METHOD_NAME) {
-          // Referencing `.call` on a `Function` type is OK.
-        } else if (result.needsGetterError) {
-          _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.UNDEFINED_GETTER,
-            propertyName,
-            [propertyName.name, targetType],
-          );
-        }
-      }
+    if (hasRead && result.needsGetterError) {
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.UNDEFINED_GETTER,
+        propertyName,
+        [propertyName.name, targetType],
+      );
+    }
 
-      if (hasWrite && result.needsSetterError) {
-        AssignmentVerifier(_definingLibrary, _errorReporter).verify(
-          node: propertyName,
-          requested: null,
-          recovery: result.getter,
-          receiverTypeObject: targetType,
-        );
-      }
+    if (hasWrite && result.needsSetterError) {
+      AssignmentVerifier(_definingLibrary, _errorReporter).verify(
+        node: propertyName,
+        requested: null,
+        recovery: result.getter,
+        receiverTypeObject: targetType,
+      );
     }
 
     return PropertyElementResolverResult(
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
index e544c4f..f9ae35c 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
@@ -111,6 +111,22 @@
         if (_hasGetterOrSetter) {
           return _toResult();
         }
+        if (receiverType.isDartCoreFunction && _name == 'call') {
+          _needsGetterError = false;
+          _needsSetterError = false;
+          return _toResult();
+        }
+      }
+
+      if (receiverType is FunctionType && _name == 'call') {
+        return _toResult();
+      }
+
+      if (receiverType is NeverType) {
+        _lookupInterfaceType(_typeProvider.objectType);
+        _needsGetterError = false;
+        _needsSetterError = false;
+        return _toResult();
       }
 
       _lookupExtension(receiverType);
diff --git a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
index d9d9872..c5129ed 100644
--- a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
@@ -558,13 +558,11 @@
   }
 
   test_binaryExpression_plus() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 void main() {
   (throw '') + (1 + 2);
 }
-''', [
-      error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 27, 1),
-    ]);
+''');
 
     assertBinaryExpression(
       findNode.binary('+ ('),
diff --git a/pkg/wasm/lib/src/function.dart b/pkg/wasm/lib/src/function.dart
index c5840bf..c138e48 100644
--- a/pkg/wasm/lib/src/function.dart
+++ b/pkg/wasm/lib/src/function.dart
@@ -9,13 +9,14 @@
 
 /// WasmFunction is a callable function from a WasmInstance.
 class WasmFunction {
+  String _name;
   Pointer<WasmerExportFunc> _func;
   List<int> _argTypes;
   int _returnType;
   Pointer<WasmerValue> _args;
   Pointer<WasmerValue> _result;
 
-  WasmFunction(this._func, this._argTypes, this._returnType) {
+  WasmFunction(this._name, this._func, this._argTypes, this._returnType) {
     _args = allocate<WasmerValue>(count: _argTypes.length);
     _result = allocate<WasmerValue>();
     for (var i = 0; i < _argTypes.length; ++i) {
@@ -46,11 +47,11 @@
 
   dynamic apply(List<dynamic> args) {
     if (args.length != _argTypes.length) {
-      throw Exception("Wrong number arguments for WASM function");
+      throw ArgumentError("Wrong number arguments for WASM function: $_name");
     }
     for (var i = 0; i < args.length; ++i) {
       if (!_fillArg(args[i], i)) {
-        throw Exception("Bad argument type for WASM function");
+        throw ArgumentError("Bad argument type for WASM function: $_name");
       }
     }
     WasmRuntime().call(_func, _args, _argTypes.length, _result,
diff --git a/pkg/wasm/lib/src/module.dart b/pkg/wasm/lib/src/module.dart
index c227eb4..d8ed0d9 100644
--- a/pkg/wasm/lib/src/module.dart
+++ b/pkg/wasm/lib/src/module.dart
@@ -73,12 +73,14 @@
       String name = runtime.exportName(e);
       if (kind == WasmerImpExpKindFunction) {
         var f = runtime.exportToFunction(e);
-        _functions[name] =
-            WasmFunction(f, runtime.getArgTypes(f), runtime.getReturnType(f));
+        _functions[name] = WasmFunction(
+            name, f, runtime.getArgTypes(f), runtime.getReturnType(f));
       }
     }
   }
 
+  /// Searches the instantiated module for the given function. Returns null if
+  /// it is not found.
   dynamic lookupFunction(String name) {
     return _functions[name];
   }
diff --git a/pkg/wasm/lib/src/runtime.dart b/pkg/wasm/lib/src/runtime.dart
index 304b9fe..6c8759a 100644
--- a/pkg/wasm/lib/src/runtime.dart
+++ b/pkg/wasm/lib/src/runtime.dart
@@ -314,7 +314,7 @@
       throw Exception("Multiple return values are not supported");
     }
     var returnsPtr = allocate<Uint32>();
-    result = _export_func_params(func, returnsPtr, 1);
+    result = _export_func_returns(func, returnsPtr, 1);
     if (result != WasmerResultOk) {
       free(returnsPtr);
       throw Exception("Failed to get WASM function args");
diff --git a/tests/lib/wasm/basic_test.dart b/tests/lib/wasm/basic_test.dart
index b6dfaa9..da2fb9a 100644
--- a/tests/lib/wasm/basic_test.dart
+++ b/tests/lib/wasm/basic_test.dart
@@ -5,7 +5,7 @@
 // Test that we can load a wasm module, find a function, and call it.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -21,8 +21,10 @@
   ]);
 
   var inst = WasmModule(data).instantiate(WasmImports());
-  var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
-  int n = fn.call([1234]);
+  var fn = inst.lookupFunction("square");
+  int n = fn(1234);
 
   Expect.equals(1234 * 1234, n);
+
+  Expect.isNull(inst.lookupFunction("not_a_function"));
 }
diff --git a/tests/lib/wasm/corrupted_error_test.dart b/tests/lib/wasm/corrupted_error_test.dart
index fcc4085..2b8d3fa 100644
--- a/tests/lib/wasm/corrupted_error_test.dart
+++ b/tests/lib/wasm/corrupted_error_test.dart
@@ -5,7 +5,7 @@
 // Test error thrown when the wasm module is corrupted.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -16,5 +16,5 @@
     0x7e, 0x0b,
   ]);
 
-  Expect.throwsArgumentError(() => WasmModule(data));
+  Expect.throws(() => WasmModule(data));
 }
diff --git a/tests/lib/wasm/fn_call_error_test.dart b/tests/lib/wasm/fn_call_error_test.dart
index 932afa3..0c74768 100644
--- a/tests/lib/wasm/fn_call_error_test.dart
+++ b/tests/lib/wasm/fn_call_error_test.dart
@@ -5,7 +5,7 @@
 // Test error thrown when a function is called with the wrong args.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -21,9 +21,9 @@
   ]);
 
   var inst = WasmModule(data).instantiate(WasmImports());
-  var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
+  var fn = inst.lookupFunction("square");
 
-  Expect.throwsArgumentError(() => fn.call([]));
-  Expect.throwsArgumentError(() => fn.call([1, 2, 3]));
-  Expect.throwsArgumentError(() => fn.call([1.23]));
+  Expect.throwsArgumentError(() => fn());
+  Expect.throwsArgumentError(() => fn(1, 2, 3));
+  Expect.throwsArgumentError(() => fn(1.23));
 }
diff --git a/tests/lib/wasm/fn_mismatch_error_test.dart b/tests/lib/wasm/fn_mismatch_error_test.dart
deleted file mode 100644
index 413260e..0000000
--- a/tests/lib/wasm/fn_mismatch_error_test.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, 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.
-
-// Test error thrown when the loaded function can't be found.
-
-import "package:expect/expect.dart";
-import "dart:wasm";
-import "dart:typed_data";
-
-void main() {
-  // int64_t square(int64_t n) { return n * n; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
-    0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
-    0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
-    0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
-    0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
-    0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
-    0x7e, 0x0b,
-  ]);
-
-  var inst = WasmModule(data).instantiate(WasmImports());
-  Expect.isNotNull(inst.lookupFunction<Int64 Function(Int64)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Int64 Function(Int64)>("blah"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Int64 Function()>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Int64 Function(Int64, Int64)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Void Function(Int64)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Void Function(dynamic)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Int64 Function(Float)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Float Function(Int64)>("square"));
-}
diff --git a/tests/lib/wasm/numerics_test.dart b/tests/lib/wasm/numerics_test.dart
index 8651caa..158549a 100644
--- a/tests/lib/wasm/numerics_test.dart
+++ b/tests/lib/wasm/numerics_test.dart
@@ -5,7 +5,7 @@
 // Test numeric types.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -30,20 +30,20 @@
   ]);
 
   var inst = WasmModule(data).instantiate(WasmImports());
-  var addI64 = inst.lookupFunction<Int64 Function(Int64, Int64)>("addI64");
-  var addI32 = inst.lookupFunction<Int32 Function(Int32, Int32)>("addI32");
-  var addF64 = inst.lookupFunction<Double Function(Double, Double)>("addF64");
-  var addF32 = inst.lookupFunction<Float Function(Float, Float)>("addF32");
+  var addI64 = inst.lookupFunction("addI64");
+  var addI32 = inst.lookupFunction("addI32");
+  var addF64 = inst.lookupFunction("addF64");
+  var addF32 = inst.lookupFunction("addF32");
 
-  int i64 = addI64.call([0x123456789ABCDEF, 0xFEDCBA987654321]);
+  int i64 = addI64(0x123456789ABCDEF, 0xFEDCBA987654321);
   Expect.equals(0x1111111111111110, i64);
 
-  int i32 = addI32.call([0xABCDEF, 0xFEDCBA]);
+  int i32 = addI32(0xABCDEF, 0xFEDCBA);
   Expect.equals(0x1aaaaa9, i32);
 
-  double f64 = addF64.call([1234.5678, 8765.4321]);
+  double f64 = addF64(1234.5678, 8765.4321);
   Expect.approxEquals(9999.9999, f64, 1e-6);
 
-  double f32 = addF32.call([1234.5678, 8765.4321]);
+  double f32 = addF32(1234.5678, 8765.4321);
   Expect.approxEquals(9999.9999, f32, 1e-3);
 }
diff --git a/tests/lib/wasm/void_test.dart b/tests/lib/wasm/void_test.dart
index fe3bd94..fe94693 100644
--- a/tests/lib/wasm/void_test.dart
+++ b/tests/lib/wasm/void_test.dart
@@ -5,7 +5,7 @@
 // Test functions with void return type, and functions that take no args.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -26,9 +26,9 @@
   ]);
 
   var inst = WasmModule(data).instantiate(WasmImports());
-  var setFn = inst.lookupFunction<Void Function(Int64, Int64)>("set");
-  var getFn = inst.lookupFunction<Int64 Function()>("get");
-  Expect.isNull(setFn.call([123, 456]));
-  int n = getFn.call([]);
+  var setFn = inst.lookupFunction("set");
+  var getFn = inst.lookupFunction("get");
+  Expect.isNull(setFn(123, 456));
+  int n = getFn();
   Expect.equals(123 + 456, n);
 }
diff --git a/tests/lib_2/wasm/basic_test.dart b/tests/lib_2/wasm/basic_test.dart
index b6dfaa9..72f4c6c 100644
--- a/tests/lib_2/wasm/basic_test.dart
+++ b/tests/lib_2/wasm/basic_test.dart
@@ -5,7 +5,7 @@
 // Test that we can load a wasm module, find a function, and call it.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -21,8 +21,10 @@
   ]);
 
   var inst = WasmModule(data).instantiate(WasmImports());
-  var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
-  int n = fn.call([1234]);
+  var fn = inst.lookupFunction("square");
+  int n = fn.call(1234);
 
   Expect.equals(1234 * 1234, n);
+
+  Expect.isNull(inst.lookupFunction("not_a_function"));
 }
diff --git a/tests/lib_2/wasm/corrupted_error_test.dart b/tests/lib_2/wasm/corrupted_error_test.dart
index fcc4085..2b8d3fa 100644
--- a/tests/lib_2/wasm/corrupted_error_test.dart
+++ b/tests/lib_2/wasm/corrupted_error_test.dart
@@ -5,7 +5,7 @@
 // Test error thrown when the wasm module is corrupted.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -16,5 +16,5 @@
     0x7e, 0x0b,
   ]);
 
-  Expect.throwsArgumentError(() => WasmModule(data));
+  Expect.throws(() => WasmModule(data));
 }
diff --git a/tests/lib_2/wasm/fn_call_error_test.dart b/tests/lib_2/wasm/fn_call_error_test.dart
index 932afa3..0c74768 100644
--- a/tests/lib_2/wasm/fn_call_error_test.dart
+++ b/tests/lib_2/wasm/fn_call_error_test.dart
@@ -5,7 +5,7 @@
 // Test error thrown when a function is called with the wrong args.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -21,9 +21,9 @@
   ]);
 
   var inst = WasmModule(data).instantiate(WasmImports());
-  var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
+  var fn = inst.lookupFunction("square");
 
-  Expect.throwsArgumentError(() => fn.call([]));
-  Expect.throwsArgumentError(() => fn.call([1, 2, 3]));
-  Expect.throwsArgumentError(() => fn.call([1.23]));
+  Expect.throwsArgumentError(() => fn());
+  Expect.throwsArgumentError(() => fn(1, 2, 3));
+  Expect.throwsArgumentError(() => fn(1.23));
 }
diff --git a/tests/lib_2/wasm/fn_mismatch_error_test.dart b/tests/lib_2/wasm/fn_mismatch_error_test.dart
deleted file mode 100644
index 413260e..0000000
--- a/tests/lib_2/wasm/fn_mismatch_error_test.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, 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.
-
-// Test error thrown when the loaded function can't be found.
-
-import "package:expect/expect.dart";
-import "dart:wasm";
-import "dart:typed_data";
-
-void main() {
-  // int64_t square(int64_t n) { return n * n; }
-  var data = Uint8List.fromList([
-    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
-    0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
-    0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
-    0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
-    0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
-    0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
-    0x7e, 0x0b,
-  ]);
-
-  var inst = WasmModule(data).instantiate(WasmImports());
-  Expect.isNotNull(inst.lookupFunction<Int64 Function(Int64)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Int64 Function(Int64)>("blah"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Int64 Function()>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Int64 Function(Int64, Int64)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Void Function(Int64)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Void Function(dynamic)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Int64 Function(Float)>("square"));
-  Expect.throwsArgumentError(
-      () => inst.lookupFunction<Float Function(Int64)>("square"));
-}
diff --git a/tests/lib_2/wasm/numerics_test.dart b/tests/lib_2/wasm/numerics_test.dart
index 8651caa..158549a 100644
--- a/tests/lib_2/wasm/numerics_test.dart
+++ b/tests/lib_2/wasm/numerics_test.dart
@@ -5,7 +5,7 @@
 // Test numeric types.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -30,20 +30,20 @@
   ]);
 
   var inst = WasmModule(data).instantiate(WasmImports());
-  var addI64 = inst.lookupFunction<Int64 Function(Int64, Int64)>("addI64");
-  var addI32 = inst.lookupFunction<Int32 Function(Int32, Int32)>("addI32");
-  var addF64 = inst.lookupFunction<Double Function(Double, Double)>("addF64");
-  var addF32 = inst.lookupFunction<Float Function(Float, Float)>("addF32");
+  var addI64 = inst.lookupFunction("addI64");
+  var addI32 = inst.lookupFunction("addI32");
+  var addF64 = inst.lookupFunction("addF64");
+  var addF32 = inst.lookupFunction("addF32");
 
-  int i64 = addI64.call([0x123456789ABCDEF, 0xFEDCBA987654321]);
+  int i64 = addI64(0x123456789ABCDEF, 0xFEDCBA987654321);
   Expect.equals(0x1111111111111110, i64);
 
-  int i32 = addI32.call([0xABCDEF, 0xFEDCBA]);
+  int i32 = addI32(0xABCDEF, 0xFEDCBA);
   Expect.equals(0x1aaaaa9, i32);
 
-  double f64 = addF64.call([1234.5678, 8765.4321]);
+  double f64 = addF64(1234.5678, 8765.4321);
   Expect.approxEquals(9999.9999, f64, 1e-6);
 
-  double f32 = addF32.call([1234.5678, 8765.4321]);
+  double f32 = addF32(1234.5678, 8765.4321);
   Expect.approxEquals(9999.9999, f32, 1e-3);
 }
diff --git a/tests/lib_2/wasm/void_test.dart b/tests/lib_2/wasm/void_test.dart
index fe3bd94..fe94693 100644
--- a/tests/lib_2/wasm/void_test.dart
+++ b/tests/lib_2/wasm/void_test.dart
@@ -5,7 +5,7 @@
 // Test functions with void return type, and functions that take no args.
 
 import "package:expect/expect.dart";
-import "dart:wasm";
+import "package:wasm/wasm.dart";
 import "dart:typed_data";
 
 void main() {
@@ -26,9 +26,9 @@
   ]);
 
   var inst = WasmModule(data).instantiate(WasmImports());
-  var setFn = inst.lookupFunction<Void Function(Int64, Int64)>("set");
-  var getFn = inst.lookupFunction<Int64 Function()>("get");
-  Expect.isNull(setFn.call([123, 456]));
-  int n = getFn.call([]);
+  var setFn = inst.lookupFunction("set");
+  var getFn = inst.lookupFunction("get");
+  Expect.isNull(setFn(123, 456));
+  int n = getFn();
   Expect.equals(123 + 456, n);
 }
diff --git a/tools/VERSION b/tools/VERSION
index 38b781d..605169e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 130
+PRERELEASE 131
 PRERELEASE_PATCH 0
\ No newline at end of file