blob: 21be20c2ce92f79af5f2feda306d71aa32d29943 [file] [log] [blame]
// Copyright (c) 2022, 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 'executor/serialization.dart'
show SerializationMode, SerializationModeHelpers;
/// Generates a Dart program for a given set of macros, which can be compiled
/// and then passed as a precompiled kernel file to `MacroExecutor.loadMacro`.
///
/// The [macroDeclarations] is a map from library URIs to macro classes for the
/// macros supported. The macro classes are provided as a map from macro class
/// names to the names of the macro class constructors.
///
/// The [serializationMode] must be a client variant.
String bootstrapMacroIsolate(
Map<String, Map<String, List<String>>> macroDeclarations,
SerializationMode serializationMode) {
StringBuffer imports = StringBuffer();
StringBuffer constructorEntries = StringBuffer();
macroDeclarations
.forEach((String macroImport, Map<String, List<String>> macroClasses) {
imports.writeln('import \'$macroImport\';');
constructorEntries.writeln("Uri.parse('$macroImport'): {");
macroClasses.forEach((String macroName, List<String> constructorNames) {
constructorEntries.writeln("'$macroName': {");
for (String constructor in constructorNames) {
constructorEntries.writeln("'$constructor': "
"$macroName.${constructor.isEmpty ? 'new' : constructor},");
}
constructorEntries.writeln('},');
});
constructorEntries.writeln('},');
});
return template
.replaceFirst(_importMarker, imports.toString())
.replaceFirst(
_macroConstructorEntriesMarker, constructorEntries.toString())
.replaceFirst(_modeMarker, serializationMode.asCode);
}
const String _importMarker = '{{IMPORT}}';
const String _macroConstructorEntriesMarker = '{{MACRO_CONSTRUCTOR_ENTRIES}}';
const String _modeMarker = '{{SERIALIZATION_MODE}}';
const String template = '''
import 'dart:io';
import 'dart:isolate';
import 'package:_macros/src/executor/client.dart';
import 'package:_macros/src/executor/serialization.dart';
$_importMarker
/// Entrypoint to be spawned with [Isolate.spawnUri] or [Process.start].
///
/// Supports the client side of the macro expansion protocol.
void main(List<String> arguments, [SendPort? sendPort]) async {
await MacroExpansionClient.start(
$_modeMarker, _macroConstructors, arguments, sendPort);
}
/// Maps libraries by uri to macros by name, and then constructors by name.
final _macroConstructors = <Uri, Map<String, Map<String, Function>>>{
$_macroConstructorEntriesMarker
};
''';