blob: 438f867e5a8b38a582a5c7d00066f8a28f0ab84c [file]
// 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 'dart:io';
import 'package:jnigen/jnigen.dart';
import 'package:jnigen/src/bindings/bindings.dart';
import 'package:jnigen/src/logging/logging.dart';
import 'package:jnigen/src/writers/bindings_writer.dart';
/// Resolver for single-file mapping of input classes.
class SingleFileResolver implements SymbolResolver {
static const predefined = {
'java.lang.String': 'jni.JString',
};
static final predefinedClasses = {
'java.lang.String': ClassDecl(
binaryName: 'java.lang.String',
packageName: 'java.lang',
simpleName: 'String',
)
..isIncluded = true
..isPreprocessed = true,
};
Map<String, ClassDecl> inputClasses;
SingleFileResolver(this.inputClasses);
@override
List<String> getImportStrings() {
return [];
}
@override
String? resolve(String binaryName) {
if (predefined.containsKey(binaryName)) return predefined[binaryName];
return inputClasses[binaryName]?.finalName;
}
@override
ClassDecl? resolveClass(String binaryName) {
if (predefinedClasses.containsKey(binaryName)) {
return predefinedClasses[binaryName];
}
return inputClasses[binaryName];
}
}
class SingleFileWriter extends BindingsWriter {
SingleFileWriter(this.config);
Config config;
@override
Future<void> writeBindings(List<ClassDecl> classes) async {
final cBased = config.outputConfig.bindingsType == BindingsType.cBased;
final preamble = config.preamble;
final Map<String, List<ClassDecl>> packages = {};
final Map<String, ClassDecl> classesByName = {};
for (var c in classes) {
classesByName.putIfAbsent(c.binaryName, () => c);
packages.putIfAbsent(c.packageName, () => <ClassDecl>[]);
packages[c.packageName]!.add(c);
}
ApiPreprocessor.preprocessAll(classesByName, config, renameClasses: true);
if (cBased) {
await writeCBindings(config, classesByName.values.toList());
}
log.info("Generating ${cBased ? "C + Dart" : "Pure Dart"} Bindings");
final generator = cBased
? CBasedDartBindingsGenerator(config)
: PureDartBindingsGenerator(config);
final file = File.fromUri(config.outputConfig.dartConfig.path);
await file.create(recursive: true);
final fileStream = file.openWrite();
final resolver = SingleFileResolver(classesByName);
// Have to generate bindings beforehand so that imports are all figured
// out.
final bindings = classesByName.values
.map((decl) => generator.generateBindings(decl, resolver))
.join("\n");
log.info("Writing Dart bindings to file: ${file.path}");
fileStream
..writeln(preamble ?? '')
..writeln(generator.getPreImportBoilerplate())
..writeln(resolver.getImportStrings().join('\n'))
..writeln(generator.getPostImportBoilerplate())
..writeln(bindings);
await fileStream.close();
await runDartFormat(file.path);
log.info('Completed');
return;
}
}