blob: c0962ffd5c8e1e2e48d3f128e0b369909058cdf9 [file] [log] [blame]
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert' show jsonDecode;
import 'dart:io' show File, InternetAddress, Socket;
final class ResidentCompilerInfo {
final String? _sdkHash;
final InternetAddress _address;
final int _port;
/// The SDK hash that kernel files compiled using the Resident Frontend
/// Compiler associated with this object will be stamped with.
String? get sdkHash => _sdkHash;
/// The address that the Resident Frontend Compiler associated with this
/// object is listening from.
InternetAddress get address => _address;
/// The port number that the Resident Frontend Compiler associated with this
/// object is listening on.
int get port => _port;
/// Extracts the value associated with a key from [entries], where [entries]
/// is a [String] with the format '$key1:$value1 $key2:$value2 ...'.
static String _extractValueAssociatedWithKey(String entries, String key) =>
new RegExp('$key:' r'(\S+)(\s|$)').allMatches(entries).first[1]!;
static ResidentCompilerInfo fromFile(File file) {
final String fileContents = file.readAsStringSync();
return new ResidentCompilerInfo._(
sdkHash: fileContents.contains('sdkHash:')
? _extractValueAssociatedWithKey(fileContents, 'sdkHash')
: null,
address: new InternetAddress(
_extractValueAssociatedWithKey(
fileContents,
'address',
),
),
port: int.parse(_extractValueAssociatedWithKey(fileContents, 'port')),
);
}
ResidentCompilerInfo._({
required String? sdkHash,
required int port,
required InternetAddress address,
}) : _sdkHash = sdkHash,
_port = port,
_address = address;
}
/// Sends a compilation [request] to the resident frontend compiler associated
/// with [serverInfoFile], and returns the compiler's JSON response.
///
/// Throws a [FileSystemException] if [serverInfoFile] cannot be accessed.
Future<Map<String, dynamic>> sendAndReceiveResponse(
String request,
File serverInfoFile,
) async {
Socket? client;
Map<String, dynamic> jsonResponse;
final ResidentCompilerInfo residentCompilerInfo =
ResidentCompilerInfo.fromFile(serverInfoFile);
try {
client = await Socket.connect(
residentCompilerInfo.address,
residentCompilerInfo.port,
);
client.write(request);
final String data = new String.fromCharCodes(await client.first);
jsonResponse = jsonDecode(data);
} catch (e) {
jsonResponse = <String, dynamic>{
'success': false,
'errorMessage': e.toString(),
};
}
client?.destroy();
return jsonResponse;
}