From 7bc0aecf4cc651f7cb2104c37875c6c056775bb0 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Fri, 19 Aug 2022 22:20:28 +0200 Subject: [PATCH] Initial draft of outline model --- .../lib/src/analysis/outline/column.dart | 74 +++++++++++++++++++ drift_dev/lib/src/analysis/outline/dart.dart | 14 ++++ .../lib/src/analysis/outline/element.dart | 22 ++++++ drift_dev/lib/src/analysis/outline/table.dart | 0 4 files changed, 110 insertions(+) create mode 100644 drift_dev/lib/src/analysis/outline/column.dart create mode 100644 drift_dev/lib/src/analysis/outline/dart.dart create mode 100644 drift_dev/lib/src/analysis/outline/element.dart create mode 100644 drift_dev/lib/src/analysis/outline/table.dart diff --git a/drift_dev/lib/src/analysis/outline/column.dart b/drift_dev/lib/src/analysis/outline/column.dart new file mode 100644 index 00000000..07667f82 --- /dev/null +++ b/drift_dev/lib/src/analysis/outline/column.dart @@ -0,0 +1,74 @@ +import 'package:drift/drift.dart' show DriftSqlType; + +import 'dart.dart'; +import 'element.dart'; + +class DriftColumn { + final DriftSqlType sqlType; + + /// Whether the user has explicitly declared this column to be nullable. + /// + /// For Dart-defined columns, this defaults to `false`. For columns defined in + /// a drift file, this value will be `true` if there is no `NOT NULL` + /// constraint present on the column's definition. + final bool nullable; + + final String nameInSql; + final String nameInDart; + + final AppliedTypeConverter? typeConverter; + + final DriftDeclaration? declaration; + + DriftColumn({ + required this.sqlType, + required this.nullable, + required this.nameInSql, + required this.nameInDart, + this.typeConverter, + this.declaration, + }); +} + +class AppliedTypeConverter { + /// The Dart expression creating an instance of the applied type converter. + final AnnotatedDartCode expression; + + final AnnotatedDartCode dartType; + final DriftSqlType sqlType; + + /// Whether the Dart-value output of this type converter is nullable. + /// + /// In other words, [dartType] is potentially nullable. + final bool dartTypeIsNullable; + + /// Whether the SQL-value output of this type converter is nullable. + /// + /// In other words, [sqlType] is potentially nullable. + final bool sqlTypeIsNullable; + + /// Whether this type converter should also be used in the generated JSON + /// serialization. + final bool alsoAppliesToJsonConversion; + + /// Whether this type converter can be skipped for `null` values. + /// + /// This applies to type converters with a non-nullable Dart and SQL type if + /// the column is nullable. For those converters, drift maps `null` to `null` + /// without calling the type converter at all. + /// + /// For nullable columns, this is implemented by wrapping it in a + /// `NullAwareTypeConverter` in the generated code for table classes. For + /// nullable references to non-nullable columns (e.g. from outer joins), this + /// is done with static helper methods on `NullAwareTypeConverter`. + bool get canBeSkippedForNulls => !dartTypeIsNullable && !sqlTypeIsNullable; + + AppliedTypeConverter({ + required this.expression, + required this.dartType, + required this.sqlType, + required this.dartTypeIsNullable, + required this.sqlTypeIsNullable, + this.alsoAppliesToJsonConversion = false, + }); +} diff --git a/drift_dev/lib/src/analysis/outline/dart.dart b/drift_dev/lib/src/analysis/outline/dart.dart new file mode 100644 index 00000000..c115b8a3 --- /dev/null +++ b/drift_dev/lib/src/analysis/outline/dart.dart @@ -0,0 +1,14 @@ +import 'element.dart'; + +class AnnotatedDartCode { + final List elements; + + AnnotatedDartCode(this.elements); +} + +class DartTopLevelSymbol { + final String lexeme; + final DriftElementId elementId; + + DartTopLevelSymbol(this.lexeme, this.elementId); +} diff --git a/drift_dev/lib/src/analysis/outline/element.dart b/drift_dev/lib/src/analysis/outline/element.dart new file mode 100644 index 00000000..a44de54d --- /dev/null +++ b/drift_dev/lib/src/analysis/outline/element.dart @@ -0,0 +1,22 @@ +import 'package:path/path.dart' show url; + +class DriftElementId { + final Uri libraryUri; + final String name; + + DriftElementId(this.libraryUri, this.name); + + bool get isDefinedInDart => url.extension(libraryUri.path) == '.dart'; + bool get isDefinedInDrift => url.extension(libraryUri.path) == '.drift'; +} + +class DriftDeclaration { + final Uri sourceUri; + final int offset; + + DriftDeclaration(this.sourceUri, this.offset); +} + +abstract class DriftElement { + DriftElementId get id; +} diff --git a/drift_dev/lib/src/analysis/outline/table.dart b/drift_dev/lib/src/analysis/outline/table.dart new file mode 100644 index 00000000..e69de29b