blob: 4899983c1cf7f689beb61aaeed32002012214458 [file] [log] [blame] [edit]
// 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 'package:path/path.dart' as path;
import 'ast/_core/interfaces/declaration.dart';
const defaultTempDirPrefix = 'swift2objc_temp_';
const symbolgraphFileSuffix = '.symbols.json';
class Command {
final String executable;
final List<String> args;
Command({required this.executable, required this.args});
}
/// Used to configure Swift2ObjC wrapper generation.
class Swift2ObjCGenerator {
/// The inputs to generate a wrapper for.
/// See `FilesInputConfig` and `ModuleInputConfig`;
final List<InputConfig> inputs;
/// The target to generate code for. If unspecified, defaults to host.
/// (e.g `x86_64-apple-ios17.0-simulator`)
final String? target;
/// The sdk to compile against. If unspecified, defaults to host.
/// (e.g `/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk`)
final Uri? sdk;
/// Specify where the wrapper swift file will be output.
final Uri outputFile;
/// Text inserted into the [outputFile] before the generated output.
final String? preamble;
/// Specify where to output the intermidiate files (i.g the symbolgraph json).
/// If this is null, a temp directory will be generated in the system temp
/// directory (using `Directory.systemTemp`) and then deleted.
/// Specifying a temp directory would prevent the tool from deleting the
/// intermediate files after generating the wrapper.
final Uri? tempDir;
/// Filter function to filter APIs
///
/// APIs can be filtered by name
///
/// Includes all declarations by default
final bool Function(Declaration declaration) include;
static bool _defaultInclude(Declaration _) => true;
const Swift2ObjCGenerator({
required this.inputs,
required this.outputFile,
this.target,
this.sdk,
this.tempDir,
this.preamble,
this.include = Swift2ObjCGenerator._defaultInclude,
});
}
/// Used to specify the inputs in the `config` object.
sealed class InputConfig {}
/// Used for `InputConfig`s that use a command to generate their symbolgraph.
abstract interface class HasSymbolgraphCommand {
Command symbolgraphCommand(String target, String sdkPath);
}
/// Used to generate a objc wrapper for one or more swift files.
class FilesInputConfig implements InputConfig, HasSymbolgraphCommand {
/// The swift file(s) to generate a wrapper for.
final List<Uri> files;
/// The name of the temporary module generated while analyzing the input
/// files. The name doesn't matter, and won't appear in generated code. But if
/// your project involves multiple Swift modules, their names must be unique.
final String tempModuleName;
const FilesInputConfig({
required this.files,
this.tempModuleName = 'symbolgraph_module',
});
@override
Command symbolgraphCommand(String target, String sdkPath) => Command(
executable: 'swiftc',
args: [
...files.map((uri) => path.absolute(uri.path)),
'-emit-module',
'-emit-symbol-graph',
'-emit-symbol-graph-dir',
'.',
'-module-name',
tempModuleName,
'-target',
target,
'-sdk',
sdkPath,
],
);
}
/// Used to generate a objc wrapper for a built-in swift module.
/// (e.g, AVFoundation)
class ModuleInputConfig implements InputConfig, HasSymbolgraphCommand {
/// The swift module to generate a wrapper for.
final String module;
const ModuleInputConfig({required this.module});
@override
Command symbolgraphCommand(String target, String sdkPath) => Command(
executable: 'swift',
args: [
'symbolgraph-extract',
'-module-name',
module,
'-target',
target,
'-sdk',
sdkPath,
'-output-dir',
'.',
],
);
}
/// Used to generate wrappers directly from a JSON symbolgraph, for debugging.
class JsonFileInputConfig implements InputConfig {
/// The JSON symbolgraph file.
final Uri jsonFile;
const JsonFileInputConfig({required this.jsonFile});
}
const builtInInputConfig = ModuleInputConfig(module: 'Foundation');