Pass language version to formatter

This commit is contained in:
Simon Binder
2024-10-23 15:39:01 +02:00
parent 17eecc91a8
commit 4c896a58ae
45 changed files with 156 additions and 51 deletions
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/_shared/todo_tables.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/_shared/todo_tables.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/modular/custom_types/drift_table.drift.dart'
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/modular/custom_types/table.drift.dart'
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/modular/drift/example.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/modular/drift/row_class.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/modular/many_to_many/shared.drift.dart'
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/modular/many_to_many/shared.drift.dart'
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/modular/many_to_many/shared.drift.dart'
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift_docs/snippets/modular/upserts.drift.dart' as i1;
+4
View File
@@ -1,3 +1,7 @@
## 2.21.1-dev
- Pass language version to dart formatter when generating code.
## 2.21.0
- Fix Dart-defined `check` constraints not being considered in exported
@@ -9,6 +9,7 @@ import '../../analysis/driver/driver.dart';
import '../../analysis/driver/state.dart';
import '../../analysis/results/results.dart';
import '../../analysis/options.dart';
import '../../utils/dartfmt.dart';
import '../../utils/string_escaper.dart';
import '../../writer/database_writer.dart';
import '../../writer/drift_accessor_writer.dart';
@@ -125,10 +126,12 @@ class _DriftBuildRun {
/// well.
Version? overriddenLanguageVersion;
/// The Dart language version from the package. When it's too old and we're
/// generating libraries, we need to apply a `// @dart` version comment to get
/// a suitable version.
Version? packageLanguageVersion;
/// The language version that that the generated file will have. This is the
/// version of the input library for part files and the default version of the
/// surrounding package otherwise.
///
/// Set in [_checkForLanguageVersions].
Version? sourceLanguageVersion;
late Writer writer;
@@ -273,7 +276,8 @@ class _DriftBuildRun {
final library = await buildStep.inputLibrary;
overriddenLanguageVersion = library.languageVersion.override;
final effectiveVersion = library.languageVersion.effective;
final effectiveVersion =
sourceLanguageVersion = library.languageVersion.effective;
if (effectiveVersion < _minimalDartLanguageVersion) {
final effective = effectiveVersion.majorMinor;
final minimum = _minimalDartLanguageVersion.majorMinor;
@@ -286,6 +290,33 @@ class _DriftBuildRun {
'file.',
);
}
} else {
// We don't have a primary library from which we'd inherit language
// versions - look it up from the package instead.
final config = await buildStep.packageConfig;
for (final package in config.packages) {
if (package.name == buildStep.inputId.package) {
final version = package.languageVersion;
if (version != null) {
final asPubSemver = Version(version.major, version.minor, 0);
if (asPubSemver < _minimalDartLanguageVersion) {
sourceLanguageVersion = _minimalDartLanguageVersion;
overriddenLanguageVersion = _minimalDartLanguageVersion;
} else {
sourceLanguageVersion = asPubSemver;
}
}
break;
}
}
if (sourceLanguageVersion == null) {
// Fallback to defaults if we were unable to resolve language versions.
sourceLanguageVersion = _minimalDartLanguageVersion;
overriddenLanguageVersion = _minimalDartLanguageVersion;
}
}
}
@@ -460,8 +491,15 @@ class _DriftBuildRun {
output.write(writer.writeGenerated());
var code = output.toString();
try {
code = DartFormatter().format(code);
code = formatDartCode(
code,
sourceLanguageVersion ?? DartFormatter.latestLanguageVersion,
// source_gen will include the linewidth comment for us.
includeWidthComment: !mode.appliesCombiningBuilderFromSourceGen &&
options.preamble == null,
);
} on FormatterException {
log.warning('Could not format generated source. The generated code is '
'probably invalid, and this is most likely a bug in drift_dev.');
@@ -1,7 +1,6 @@
import 'dart:convert';
import 'dart:io';
import 'package:dart_style/dart_style.dart';
import 'package:drift_dev/src/analysis/results/results.dart';
import 'package:drift_dev/src/cli/cli.dart';
import 'package:drift_dev/src/cli/commands/schema.dart';
@@ -138,7 +137,7 @@ targets:
await writer.writeTestDatabases();
// Write the generated test
await writer.writeTest();
writer.flush();
await writer.flush();
}
}
}
@@ -179,12 +178,10 @@ class _MigrationTestEmitter {
final writeTasks = <File, String>{};
/// Write all the files to the disk
void flush() {
Future<void> flush() async {
for (var MapEntry(key: file, value: content) in writeTasks.entries) {
if (file.path.endsWith('.dart')) {
content = DartFormatter().format(content);
}
file.writeAsStringSync(content);
// Note: Content is formatted Dart code at this point.
await file.writeAsString(content);
}
writeTasks.clear();
}
@@ -317,7 +314,7 @@ ${blue.wrap("class")} ${green.wrap(dbClassName)} ${blue.wrap("extends")} ${green
"$dbName: Updating step by step migration helper in ${blue.wrap(p.relative(stepsFile.path))}");
}
writeTasks[stepsFile] =
StepsGenerationUtil.generateStepByStepMigration(schemas);
await StepsGenerationUtil.generateStepByStepMigration(cli, schemas);
}
/// Generate a built database for each schema version
@@ -327,10 +324,11 @@ ${blue.wrap("class")} ${green.wrap(dbClassName)} ${blue.wrap("extends")} ${green
final version = versionAndEntities.key;
final entities = versionAndEntities.value;
writeTasks[testUtilityFile(version)] =
GenerateUtils.generateSchemaCode(cli, version, entities, true, true);
await GenerateUtils.generateSchemaCode(
cli, version, entities, true, true);
}
writeTasks[File(p.join(testDatabasesDir.path, 'schema.dart'))] =
GenerateUtils.generateLibraryCode(schemas.keys);
await GenerateUtils.generateLibraryCode(cli, schemas.keys);
}
Future<void> writeTest() async {
@@ -400,7 +398,7 @@ void main() {
cli.logger.info(
'$dbName: Generated test in ${blue.wrap(p.relative(testFile.path))}.\n'
'Run this test to validate that your migrations are written correctly. ${yellow.wrap("dart test ${p.relative(testFile.path)}")}');
writeTasks[testFile] = code;
writeTasks[testFile] = await cli.project.formatSource(code);
}
/// The json file where the schema for the current version of the database is stored
@@ -3,7 +3,6 @@ import 'dart:io';
import 'dart:isolate';
import 'package:args/command_runner.dart';
import 'package:dart_style/dart_style.dart';
import 'package:drift/drift.dart' show SqlDialect;
import '../../../analysis/options.dart';
@@ -101,12 +100,11 @@ void main(List<String> args, SendPort port) {
final input = DatabaseGenerationInput(database, resolved, const {}, null);
DatabaseWriter(input, writer.child()).write();
final output = _dartfmt.format(writer.writeGenerated());
final receive = ReceivePort();
final receiveErrors = ReceivePort();
final isolate = await Isolate.spawnUri(
Uri.dataFromString(output),
Uri.dataFromString(writer.writeGenerated()),
[dialect.name],
receive.sendPort,
errorsAreFatal: true,
@@ -134,8 +132,6 @@ void main(List<String> args, SendPort port) {
receiveErrors.close();
receive.close();
}
static final _dartfmt = DartFormatter();
}
extension<T> on Stream<T> {
@@ -1,7 +1,6 @@
import 'dart:io';
import 'package:args/command_runner.dart';
import 'package:dart_style/dart_style.dart';
import 'package:path/path.dart' as p;
import 'package:collection/collection.dart';
@@ -69,7 +68,7 @@ class GenerateUtilsCommand extends Command {
final file = File(
p.join(outputDir.path, GenerateUtils._filenameForVersion(version)));
await file.writeAsString(GenerateUtils.generateSchemaCode(
await file.writeAsString(await GenerateUtils.generateSchemaCode(
cli,
version,
entities,
@@ -80,7 +79,7 @@ class GenerateUtilsCommand extends Command {
final versions = schema.keys.toList()..sort();
final libraryFile = File(p.join(outputDir.path, 'schema.dart'));
await libraryFile
.writeAsString(GenerateUtils.generateLibraryCode(versions));
.writeAsString(await GenerateUtils.generateLibraryCode(cli, versions));
print(
'Wrote ${schema.length + 1} files into ${p.relative(outputDir.path)}');
}
@@ -90,16 +89,15 @@ class GenerateUtils {
static String _filenameForVersion(int version) => 'schema_v$version.dart';
static const _prefix = '// GENERATED CODE, DO NOT EDIT BY HAND.\n'
'// ignore_for_file: type=lint';
static final _dartfmt = DartFormatter();
/// Generates Dart code for a specific schema version.
static String generateSchemaCode(
static Future<String> generateSchemaCode(
DriftDevCli cli,
int version,
ExportedSchema schema,
bool dataClasses,
bool companions,
) {
) async {
// let serialized options take precedence, otherwise use current options
// from project.
final options = DriftOptions.fromJson({
@@ -120,7 +118,6 @@ class GenerateUtils {
writer.leaf()
..writeln(_prefix)
..writeln('//@dart=2.12')
..writeln("import 'package:drift/drift.dart';");
final database = DriftDatabase(
@@ -137,15 +134,15 @@ class GenerateUtils {
DatabaseWriter(input, writer.child()).write();
return _dartfmt.format(writer.writeGenerated());
return await cli.project.formatSource(writer.writeGenerated());
}
/// Generates the Dart code for a library file that instantiates the schema
/// for each version.
static String generateLibraryCode(Iterable<int> versions) {
static Future<String> generateLibraryCode(
DriftDevCli cli, Iterable<int> versions) async {
final buffer = StringBuffer()
..writeln(_prefix)
..writeln('//@dart=2.12')
..writeln("import 'package:drift/drift.dart';")
..writeln("import 'package:drift/internal/migrations.dart';");
@@ -177,6 +174,6 @@ class GenerateUtils {
..writeln('static const versions = const $versionsSet;')
..writeln('}');
return _dartfmt.format(buffer.toString());
return await cli.project.formatSource(buffer.toString());
}
}
@@ -49,13 +49,14 @@ class WriteVersions extends Command {
}
final schemas = await parseSchema(inputDirectory);
await outputFile.writeAsString(
StepsGenerationUtil.generateStepByStepMigration(schemas));
await StepsGenerationUtil.generateStepByStepMigration(cli, schemas));
}
}
class StepsGenerationUtil {
/// Generate dart code for incremental migrations between schema versions.
static String generateStepByStepMigration(Map<int, ExportedSchema> schemas) {
static Future<String> generateStepByStepMigration(
DriftDevCli cli, Map<int, ExportedSchema> schemas) async {
final imports = LibraryImportManager();
final writer = Writer(
const DriftOptions.defaults(),
@@ -78,7 +79,7 @@ class StepsGenerationUtil {
var code = writer.writeGenerated();
try {
code = DartFormatter().format(code);
code = await cli.project.formatSource(code);
} on FormatterException {
// Ignore. Probably a bug in drift_dev, the user will notice.
}
+27 -2
View File
@@ -1,19 +1,24 @@
import 'dart:io';
import 'package:build_config/build_config.dart';
import 'package:dart_style/dart_style.dart';
import 'package:drift_dev/src/analysis/options.dart';
import 'package:drift_dev/src/utils/dartfmt.dart';
import 'package:drift_dev/src/utils/options_reader.dart';
import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';
import 'package:stream_transform/stream_transform.dart';
/// A project using moor. This is typically a dart project with a dependency on
/// moor and moor_generator.
/// A project using drift. This is typically a dart project with a dependency on
/// drift and drift_dev.
class DriftProject {
/// The build configuration for this project.
final BuildConfig buildConfig;
final DriftOptions options;
final Directory directory;
Version? _languageVersion;
DriftProject(this.buildConfig, this.directory)
: options = readOptionsFromConfig(buildConfig);
@@ -34,6 +39,26 @@ class DriftProject {
}).whereType();
}
Future<Version> inferLanguageVersion() async {
if (_languageVersion != null) {
return _languageVersion!;
}
final config = await findPackageConfig(directory);
if (config == null) {
return _languageVersion = DartFormatter.latestLanguageVersion;
}
final package = config.packageOf(Uri.file(p.join(directory.path, 'lib')));
return _languageVersion = package?.languageVersion?.asPubSemver ??
DartFormatter.latestLanguageVersion;
}
Future<String> formatSource(String source) async {
final version = await inferLanguageVersion();
return formatDartCode(source, version);
}
static Future<DriftProject> readFromDir(Directory directory) async {
final config = await BuildConfig.fromPackageDir(directory.path);
+22
View File
@@ -0,0 +1,22 @@
import 'package:dart_style/dart_style.dart';
import 'package:package_config/package_config_types.dart';
import 'package:pub_semver/pub_semver.dart';
String formatDartCode(
String code,
Version version, {
bool includeWidthComment = true,
}) {
var input = includeWidthComment
? '''
// dart format width=80
$code
'''
: code;
return DartFormatter(languageVersion: version).format(input);
}
extension LanguageVersionToPubSember on LanguageVersion {
Version get asPubSemver => Version(major, minor, 0);
}
+1 -1
View File
@@ -49,7 +49,7 @@ dependencies:
build: ^2.0.0
build_resolvers: ^2.4.0
build_config: ">=0.3.1 <2.0.0"
dart_style: ">=1.3.3 <3.0.0"
dart_style: "^2.3.7"
source_gen: ">=0.9.4 <2.0.0"
string_scanner: ^1.1.1
@@ -1,3 +1,4 @@
// dart format width=80
import 'package:drift/internal/versioned_schema.dart' as i0;
import 'package:drift/drift.dart' as i1;
import 'package:drift/src/runtime/query_builder/query_builder.dart' as i2;
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
import 'package:drift/internal/migrations.dart';
import 'schema_v9.dart' as v9;
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
@@ -1,6 +1,6 @@
// dart format width=80
// GENERATED CODE, DO NOT EDIT BY HAND.
// ignore_for_file: type=lint
//@dart=2.12
import 'package:drift/drift.dart';
class Users extends Table with TableInfo<Users, UsersData> {
+1
View File
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:modular/database.dart' as i1;
+1
View File
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:modular/src/users.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:modular/src/posts.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:modular/src/search.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift/internal/modular.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:modular/src/users.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:shared/src/users.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:shared/src/users.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:drift/internal/modular.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:shared/src/posts.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:shared/src/users.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:with_built_value/tables.drift.dart' as i1;
@@ -1,3 +1,4 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:with_built_value/tables.drift.dart' as i1;