diff --git a/drift_dev/lib/src/analysis/resolver/drift/view.dart b/drift_dev/lib/src/analysis/resolver/drift/view.dart index a24f9cfc..f4f5a076 100644 --- a/drift_dev/lib/src/analysis/resolver/drift/view.dart +++ b/drift_dev/lib/src/analysis/resolver/drift/view.dart @@ -22,15 +22,17 @@ class DriftViewResolver extends DriftElementResolver { final engine = newEngineWithTables(references); final source = (file.discovery as DiscoveredDriftFile).originalSource; + final resolveTypes = allReferences.dartTypes.isEmpty + ? null + : await createTypeResolver( + allReferences, + await resolver.driver.loadKnownTypes(), + ); + final context = engine.analyzeNode( stmt, source, - stmtOptions: AnalyzeStatementOptions( - resolveTypeFromText: await createTypeResolver( - allReferences, - await resolver.driver.loadKnownTypes(), - ), - ), + stmtOptions: AnalyzeStatementOptions(resolveTypeFromText: resolveTypes), ); reportLints(context, references); diff --git a/drift_dev/lib/src/writer/tables/table_writer.dart b/drift_dev/lib/src/writer/tables/table_writer.dart index c5d0ce4c..0f848ee7 100644 --- a/drift_dev/lib/src/writer/tables/table_writer.dart +++ b/drift_dev/lib/src/writer/tables/table_writer.dart @@ -154,6 +154,36 @@ abstract class TableOrViewWriter { ); } + void writeConvertersAsStaticFields() { + for (final converter in tableOrView.appliedConverters) { + if (converter.owningColumn?.owner != tableOrView) continue; + + final typeName = + emitter.dartCode(emitter.writer.converterType(converter)); + final code = emitter.dartCode(converter.expression); + + buffer.write('static $typeName ${converter.fieldName} = $code;'); + + // Generate wrappers for non-nullable type converters that are applied to + // nullable converters. + final column = converter.owningColumn!; + if (converter.canBeSkippedForNulls && column.nullable) { + final nullableTypeName = emitter.dartCode( + emitter.writer.converterType(converter, makeNullable: true)); + + final wrap = converter.alsoAppliesToJsonConversion + ? emitter.drift('JsonTypeConverter2.asNullable') + : emitter.drift('NullAwareTypeConverter.wrap'); + + final code = '$wrap(${converter.fieldName})'; + + buffer + .write('static $nullableTypeName ${converter.nullableFieldName} = ' + '$code;'); + } + } + } + void writeMappingMethod(Scope scope) { if (!scope.generationOptions.writeDataClasses) { buffer.writeln(''' @@ -359,7 +389,7 @@ class TableWriter extends TableOrViewWriter { _writeAliasGenerator(); - _writeConvertersAsStaticFields(); + writeConvertersAsStaticFields(); _overrideFieldsIfNeeded(); // close class @@ -384,34 +414,6 @@ class TableWriter extends TableOrViewWriter { buffer.write('}'); } - void _writeConvertersAsStaticFields() { - for (final converter in table.appliedConverters) { - final typeName = - emitter.dartCode(emitter.writer.converterType(converter)); - final code = emitter.dartCode(converter.expression); - - buffer.write('static $typeName ${converter.fieldName} = $code;'); - - // Generate wrappers for non-nullable type converters that are applied to - // nullable converters. - final column = converter.owningColumn!; - if (converter.canBeSkippedForNulls && column.nullable) { - final nullableTypeName = emitter.dartCode( - emitter.writer.converterType(converter, makeNullable: true)); - - final wrap = converter.alsoAppliesToJsonConversion - ? emitter.drift('JsonTypeConverter2.asNullable') - : emitter.drift('NullAwareTypeConverter.wrap'); - - final code = '$wrap(${converter.fieldName})'; - - buffer - .write('static $nullableTypeName ${converter.nullableFieldName} = ' - '$code;'); - } - } - } - void _writeColumnVerificationMeta(DriftColumn column) { if (!_skipVerification) { final meta = emitter.drift('VerificationMeta'); diff --git a/drift_dev/lib/src/writer/tables/view_writer.dart b/drift_dev/lib/src/writer/tables/view_writer.dart index 79350cf3..659b8843 100644 --- a/drift_dev/lib/src/writer/tables/view_writer.dart +++ b/drift_dev/lib/src/writer/tables/view_writer.dart @@ -107,6 +107,7 @@ class ViewWriter extends TableOrViewWriter { Set get readTables => const {$readTables}; '''); + writeConvertersAsStaticFields(); buffer.writeln('}'); } diff --git a/drift_dev/test/analysis/resolver/dart/type_converter_test.dart b/drift_dev/test/analysis/resolver/dart/type_converter_test.dart index abb17213..11952069 100644 --- a/drift_dev/test/analysis/resolver/dart/type_converter_test.dart +++ b/drift_dev/test/analysis/resolver/dart/type_converter_test.dart @@ -32,7 +32,7 @@ class Users extends Table { } ''', 'a|lib/main.drift': ''' -import 'main.dart'; +import 'json.dart'; CREATE TABLE users ( foo TEXT MAPPED BY `withoutJson()`, @@ -93,5 +93,5 @@ CREATE TABLE users ( test('json converters in drift files', () { return testWith('package:a/main.drift'); - }, skip: 'Reading Dart expressions not currently supported in tests'); + }); } diff --git a/drift_dev/test/backends/build/build_integration_test.dart b/drift_dev/test/backends/build/build_integration_test.dart index cca6d38a..41bd2353 100644 --- a/drift_dev/test/backends/build/build_integration_test.dart +++ b/drift_dev/test/backends/build/build_integration_test.dart @@ -273,4 +273,50 @@ class ADrift extends i1.ModularAccessor { ''')), }, results.dartOutputs, results); }); + + test('generates type converters for views', () async { + final result = await emulateDriftBuild( + inputs: { + 'a|lib/a.drift': ''' +import 'converter.dart'; + +CREATE VIEW my_view AS SELECT + CAST(1 AS ENUM(MyEnum)) AS c1, + CAST('bar' AS ENUMNAME(MyEnum)) AS c2, + 1 MAPPED BY `myConverter()` AS c3, + NULLIF(1, 2) MAPPED BY `myConverter()` AS c4 +; +''', + 'a|lib/converter.dart': ''' +import 'package:drift/drift.dart'; + +enum MyEnum { + foo, bar +} + +TypeConverter myConverter() => throw UnimplementedError(); +''', + }, + modularBuild: true, + logger: loggerThat(neverEmits(anything)), + ); + + checkOutputs( + { + 'a|lib/a.drift.dart': decodedMatches( + allOf( + contains( + ''''CREATE VIEW my_view AS SELECT CAST(1 AS INT) AS c1, CAST(\\'bar\\' AS TEXT) AS c2, 1 AS c3, NULLIF(1, 2) AS c4';'''), + contains(r'$converterc1 ='), + contains(r'$converterc2 ='), + contains(r'$converterc3 ='), + contains(r'$converterc4 ='), + contains(r'$converterc4n ='), + ), + ), + }, + result.dartOutputs, + result, + ); + }); }