Skip to content

Commit 3c30561

Browse files
author
Anna Gringauze
authored
Migrate frontend-server-common to null safety (#1650)
* Remove dead code * Remove abstract ResidentCompiler class * Migrate events and utilities to null safety * Migrate some of dwds files to null safety * Migrate frontend_server_common to null safety * Fixed bad merge * Fixed analyzer warning * Address CR comments * Addressed CR comments * Format * Address CR comments * Address CR comments, make fields of StdoutHandler private
1 parent da5597a commit 3c30561

File tree

7 files changed

+217
-214
lines changed

7 files changed

+217
-214
lines changed

frontend_server_common/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 0.2.0
2+
- Migrate to null safety
3+
14
## 0.1.1
25
- Remove dead code
36

frontend_server_common/lib/src/asset_server.dart

+46-43
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.9
6-
75
// Note: this is a copy from flutter tools, updated to work with dwds tests
86

97
import 'dart:async';
108
import 'dart:convert';
119
import 'dart:io';
1210
import 'dart:typed_data';
1311

14-
import 'package:dwds/dwds.dart';
12+
import 'package:dwds/asset_reader.dart';
1513
import 'package:file/file.dart';
1614
import 'package:logging/logging.dart';
1715
import 'package:mime/mime.dart' as mime;
@@ -32,10 +30,10 @@ class TestAssetServer implements AssetReader {
3230
static const String _defaultMimeType = 'application/octet-stream';
3331
final FileSystem _fileSystem;
3432
final HttpServer _httpServer;
35-
final Map<String, Uint8List> _files = <String, Uint8List>{};
36-
final Map<String, Uint8List> _sourcemaps = <String, Uint8List>{};
37-
final Map<String, Uint8List> _metadata = <String, Uint8List>{};
38-
String _mergedMetadata;
33+
final Map<String, Uint8List> _files = {};
34+
final Map<String, Uint8List> _sourceMaps = {};
35+
final Map<String, Uint8List> _metadata = {};
36+
late String _mergedMetadata;
3937
final PackageConfig _packageConfig;
4038
final InternetAddress internetAddress;
4139

@@ -47,6 +45,15 @@ class TestAssetServer implements AssetReader {
4745
this._fileSystem,
4846
) : basePath = _parseBasePathFromIndexHtml(index);
4947

48+
bool hasFile(String path) => _files.containsKey(path);
49+
Uint8List getFile(String path) => _files[path]!;
50+
51+
bool hasSourceMap(String path) => _sourceMaps.containsKey(path);
52+
Uint8List getSourceMap(String path) => _sourceMaps[path]!;
53+
54+
bool hasMetadata(String path) => _metadata.containsKey(path);
55+
Uint8List getMetadata(String path) => _metadata[path]!;
56+
5057
/// Start the web asset server on a [hostname] and [port].
5158
///
5259
/// Unhandled exceptions will throw a exception with the error and stack
@@ -66,10 +73,6 @@ class TestAssetServer implements AssetReader {
6673
return server;
6774
}
6875

69-
Uint8List getFile(String path) => _files[path];
70-
71-
Uint8List getSourceMap(String path) => _sourcemaps[path];
72-
7376
// handle requests for JavaScript source, dart sources maps, or asset files.
7477
Future<shelf.Response> handleRequest(shelf.Request request) async {
7578
var headers = <String, String>{};
@@ -94,21 +97,18 @@ class TestAssetServer implements AssetReader {
9497
requestPath = _stripBasePath(requestPath, basePath) ?? requestPath;
9598

9699
requestPath = requestPath.startsWith('/') ? requestPath : '/$requestPath';
97-
if (requestPath == null) {
98-
return shelf.Response.notFound('');
99-
}
100100

101101
// If this is a JavaScript file, it must be in the in-memory cache.
102102
// Attempt to look up the file by URI.
103-
if (_files.containsKey(requestPath)) {
103+
if (hasFile(requestPath)) {
104104
final List<int> bytes = getFile(requestPath);
105105
headers[HttpHeaders.contentLengthHeader] = bytes.length.toString();
106106
headers[HttpHeaders.contentTypeHeader] = 'application/javascript';
107107
return shelf.Response.ok(bytes, headers: headers);
108108
}
109109
// If this is a sourcemap file, then it might be in the in-memory cache.
110110
// Attempt to lookup the file by URI.
111-
if (_sourcemaps.containsKey(requestPath)) {
111+
if (hasSourceMap(requestPath)) {
112112
final List<int> bytes = getSourceMap(requestPath);
113113
headers[HttpHeaders.contentLengthHeader] = bytes.length.toString();
114114
headers[HttpHeaders.contentTypeHeader] = 'application/json';
@@ -124,7 +124,7 @@ class TestAssetServer implements AssetReader {
124124
// Attempt to determine the file's mime type. if this is not provided some
125125
// browsers will refuse to render images/show video et cetera. If the tool
126126
// cannot determine a mime type, fall back to application/octet-stream.
127-
String mimeType;
127+
String? mimeType;
128128
if (length >= 12) {
129129
mimeType = mime.lookupMimeType(
130130
file.path,
@@ -160,10 +160,6 @@ class TestAssetServer implements AssetReader {
160160
var manifest =
161161
_castStringKeyedMap(json.decode(manifestFile.readAsStringSync()));
162162
for (var filePath in manifest.keys) {
163-
if (filePath == null) {
164-
_logger.severe('Invalid manfiest file: $filePath');
165-
continue;
166-
}
167163
var offsets = _castStringKeyedMap(manifest[filePath]);
168164
var codeOffsets = (offsets['code'] as List<dynamic>).cast<int>();
169165
var sourcemapOffsets =
@@ -200,7 +196,7 @@ class TestAssetServer implements AssetReader {
200196
sourcemapStart,
201197
sourcemapEnd - sourcemapStart,
202198
);
203-
_sourcemaps['$filePath.map'] = sourcemapView;
199+
_sourceMaps['$filePath.map'] = sourcemapView;
204200

205201
var metadataStart = metadataOffsets[0];
206202
var metadataEnd = metadataOffsets[1];
@@ -259,36 +255,42 @@ class TestAssetServer implements AssetReader {
259255
}
260256

261257
@override
262-
Future<String> dartSourceContents(String serverPath) {
263-
serverPath = _stripBasePath(serverPath, basePath);
264-
var result = _resolveDartFile(serverPath);
265-
if (result.existsSync()) {
266-
return result.readAsString();
258+
Future<String?> dartSourceContents(String serverPath) async {
259+
final stripped = _stripBasePath(serverPath, basePath);
260+
if (stripped != null) {
261+
var result = _resolveDartFile(stripped);
262+
if (result.existsSync()) {
263+
return result.readAsString();
264+
}
267265
}
268266
_logger.severe('Source not found: $serverPath');
269267
return null;
270268
}
271269

272270
@override
273-
Future<String> sourceMapContents(String serverPath) async {
274-
serverPath = _stripBasePath(serverPath, basePath);
275-
var path = '/$serverPath';
276-
if (_sourcemaps.containsKey(path)) {
277-
return utf8.decode(_sourcemaps[path]);
271+
Future<String?> sourceMapContents(String serverPath) async {
272+
final stripped = _stripBasePath(serverPath, basePath);
273+
if (stripped != null) {
274+
var path = '/$stripped';
275+
if (hasSourceMap(path)) {
276+
return utf8.decode(getSourceMap(path));
277+
}
278278
}
279279
_logger.severe('Source map not found: $serverPath');
280280
return null;
281281
}
282282

283283
@override
284-
Future<String> metadataContents(String serverPath) async {
285-
serverPath = _stripBasePath(serverPath, basePath);
286-
if (serverPath.endsWith('.ddc_merged_metadata')) {
287-
return _mergedMetadata;
288-
}
289-
var path = '/$serverPath';
290-
if (_metadata.containsKey(path)) {
291-
return utf8.decode(_metadata[path]);
284+
Future<String?> metadataContents(String serverPath) async {
285+
final stripped = _stripBasePath(serverPath, basePath);
286+
if (stripped != null) {
287+
if (stripped.endsWith('.ddc_merged_metadata')) {
288+
return _mergedMetadata;
289+
}
290+
var path = '/$stripped';
291+
if (hasMetadata(path)) {
292+
return utf8.decode(getMetadata(path));
293+
}
292294
}
293295
_logger.severe('Metadata not found: $serverPath');
294296
return null;
@@ -299,7 +301,7 @@ class TestAssetServer implements AssetReader {
299301
/// the same structure (`Map<String, dynamic>`) with the correct runtime types.
300302
Map<String, dynamic> _castStringKeyedMap(dynamic untyped) {
301303
var map = untyped as Map<dynamic, dynamic>;
302-
return map?.cast<String, dynamic>();
304+
return map.cast<String, dynamic>();
303305
}
304306

305307
String _stripLeadingSlashes(String path) {
@@ -309,7 +311,7 @@ String _stripLeadingSlashes(String path) {
309311
return path;
310312
}
311313

312-
String _stripBasePath(String path, String basePath) {
314+
String? _stripBasePath(String path, String basePath) {
313315
path = _stripLeadingSlashes(path);
314316
if (path.startsWith(basePath)) {
315317
path = path.substring(basePath.length);
@@ -327,5 +329,6 @@ String _parseBasePathFromIndexHtml(String index) {
327329
}
328330
final contents = file.readAsStringSync();
329331
final matches = RegExp(r'<base href="/([^>]*)/">').allMatches(contents);
330-
return matches.isEmpty ? '' : matches.first.group(1);
332+
if (matches.isEmpty) return '';
333+
return matches.first.group(1) ?? '';
331334
}

frontend_server_common/lib/src/bootstrap.dart

+4-8
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.9
6-
75
// Note: this is a copy from flutter tools, updated to work with dwds tests
86

9-
import 'package:meta/meta.dart';
10-
117
/// The JavaScript bootstrap script to support in-browser hot restart.
128
///
139
/// The [requireUrl] loads our cached RequireJS script file. The [mapperUrl]
@@ -18,9 +14,9 @@ import 'package:meta/meta.dart';
1814
/// and is responsible for bootstrapping the RequireJS modules and attaching
1915
/// the hot reload hooks.
2016
String generateBootstrapScript({
21-
@required String requireUrl,
22-
@required String mapperUrl,
23-
@required String entrypoint,
17+
required String requireUrl,
18+
required String mapperUrl,
19+
required String entrypoint,
2420
}) {
2521
return '''
2622
"use strict";
@@ -53,7 +49,7 @@ document.head.appendChild(requireEl);
5349
/// the file `foo/bar/baz.dart` will generate a property named approximately
5450
/// `foo__bar__baz`. Rather than attempt to guess, we assume the first property of
5551
/// this object is the module.
56-
String generateMainModule({@required String entrypoint}) {
52+
String generateMainModule({required String entrypoint}) {
5753
return '''/* ENTRYPOINT_EXTENTION_MARKER */
5854
5955
// Create the main module loaded below.

frontend_server_common/lib/src/devfs.dart

+18-25
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.9
6-
75
// Note: this is a copy from flutter tools, updated to work with dwds tests
86

97
import 'dart:io';
108

11-
import 'package:dwds/dwds.dart';
9+
import 'package:dwds/asset_reader.dart';
1210
import 'package:file/file.dart';
13-
import 'package:meta/meta.dart';
1411
import 'package:package_config/package_config.dart';
1512
import 'package:path/path.dart' as p;
1613

@@ -23,28 +20,27 @@ final String dartWebSdkPath = p.join(dartSdkPath, 'lib', 'dev_compiler');
2320

2421
class WebDevFS {
2522
WebDevFS({
26-
this.fileSystem,
27-
this.hostname,
28-
this.port,
29-
this.projectDirectory,
30-
this.packageConfigFile,
31-
this.index,
32-
this.urlTunneller,
33-
this.soundNullSafety,
23+
required this.fileSystem,
24+
required this.hostname,
25+
required this.port,
26+
required this.projectDirectory,
27+
required this.packageConfigFile,
28+
required this.index,
29+
required this.urlTunneller,
30+
required this.soundNullSafety,
3431
});
3532

3633
final FileSystem fileSystem;
37-
TestAssetServer assetServer;
34+
late final TestAssetServer assetServer;
3835
final String hostname;
3936
final int port;
4037
final Uri projectDirectory;
4138
final Uri packageConfigFile;
4239
final String index;
4340
final UrlEncoder urlTunneller;
4441
final bool soundNullSafety;
45-
Directory _savedCurrentDirectory;
46-
List<Uri> sources;
47-
PackageConfig _packageConfig;
42+
late final Directory _savedCurrentDirectory;
43+
late final PackageConfig _packageConfig;
4844

4945
Future<Uri> create() async {
5046
_savedCurrentDirectory = fileSystem.currentDirectory;
@@ -61,16 +57,15 @@ class WebDevFS {
6157

6258
Future<void> dispose() {
6359
fileSystem.currentDirectory = _savedCurrentDirectory;
64-
return assetServer?.close();
60+
return assetServer.close();
6561
}
6662

6763
Future<UpdateFSReport> update({
68-
Uri mainUri,
69-
String dillOutputPath,
70-
@required ResidentCompiler generator,
71-
List<Uri> invalidatedFiles,
64+
required Uri mainUri,
65+
required String dillOutputPath,
66+
required ResidentCompiler generator,
67+
required List<Uri> invalidatedFiles,
7268
}) async {
73-
assert(generator != null);
7469
final mainPath = mainUri.toFilePath();
7570
final outputDirectoryPath = fileSystem.file(mainPath).parent.path;
7671
final entryPoint = mainUri.toString();
@@ -108,8 +103,6 @@ class WebDevFS {
108103
return UpdateFSReport(success: false);
109104
}
110105

111-
// list of sources that needs to be monitored are in [compilerOutput.sources]
112-
sources = compilerOutput.sources;
113106
File codeFile;
114107
File manifestFile;
115108
File sourcemapFile;
@@ -200,7 +193,7 @@ class UpdateFSReport {
200193
/// mode.
201194
///
202195
/// Only used for JavaScript compilation.
203-
List<String> invalidatedModules;
196+
List<String>? invalidatedModules;
204197
}
205198

206199
String _filePathToUriFragment(String path) {

0 commit comments

Comments
 (0)