mirror of https://github.com/AMT-Cheif/drift.git
First draft for intermediate results
This commit is contained in:
parent
b088537b81
commit
5e4a65eace
|
@ -1,7 +1,9 @@
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
abstract class DriftBackend {
|
abstract class DriftBackend {
|
||||||
Logger get log;
|
Logger get log;
|
||||||
|
|
||||||
Future<String> readAsString(Uri uri);
|
Future<String> readAsString(Uri uri);
|
||||||
|
Future<LibraryElement> readDart(Uri uri);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
import 'package:path/path.dart' show url;
|
||||||
|
|
||||||
|
import 'results/element.dart';
|
||||||
|
|
||||||
|
class DriftAnalysisCache {
|
||||||
|
final Map<Uri, FileState> knownFiles = {};
|
||||||
|
final Map<DriftElementId, PendingDriftElement> knownElements = {};
|
||||||
|
|
||||||
|
FileState notifyFileChanged(Uri uri) {
|
||||||
|
// todo: Mark references for files that import this one as stale.
|
||||||
|
// todo: Mark elements that reference an element in this file as stale.
|
||||||
|
|
||||||
|
return knownFiles.putIfAbsent(uri, () => FileState(uri))
|
||||||
|
..errors.clear()
|
||||||
|
..kind = null
|
||||||
|
..parsedDartFile = null
|
||||||
|
..parsedDriftFile = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void notifyFileDeleted(Uri uri) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A [DriftElement] that is known to exist, but perhaps hasn't fully been
|
||||||
|
/// resolved yet.
|
||||||
|
class PendingDriftElement {
|
||||||
|
final DriftElementId ownId;
|
||||||
|
final List<Dependency> dependencies;
|
||||||
|
|
||||||
|
bool cleanState = false;
|
||||||
|
bool isOnCircularReferencePath = false;
|
||||||
|
|
||||||
|
PendingDriftElement(this.ownId, List<Dependency> dependencies)
|
||||||
|
: dependencies = UnmodifiableListView(dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Dependency {}
|
||||||
|
|
||||||
|
class ReferencesElement extends Dependency {
|
||||||
|
final DriftElementId referencedElement;
|
||||||
|
|
||||||
|
ReferencesElement(this.referencedElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReferencesUnknownElement extends Dependency {
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
ReferencesUnknownElement(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FileKind {
|
||||||
|
driftFile,
|
||||||
|
dartLibrary,
|
||||||
|
|
||||||
|
/// A Dart part file, a file with an unknown extension or a file that doesn't
|
||||||
|
/// exist.
|
||||||
|
invalid,
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileState {
|
||||||
|
final Uri uri;
|
||||||
|
|
||||||
|
final List<DriftElementId> locallyDefinedElements = [];
|
||||||
|
final List<Uri> directImports = [];
|
||||||
|
final List<AnalysisError> errors = [];
|
||||||
|
|
||||||
|
bool contentsFresh = false;
|
||||||
|
bool referencesFresh = false;
|
||||||
|
|
||||||
|
FileKind? kind;
|
||||||
|
DriftFile? parsedDriftFile;
|
||||||
|
LibraryElement? parsedDartFile;
|
||||||
|
|
||||||
|
FileState(this.uri);
|
||||||
|
|
||||||
|
String get extension => url.extension(uri.path);
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
import '../analyzer/options.dart';
|
||||||
|
import 'backend.dart';
|
||||||
|
import 'cache.dart';
|
||||||
|
|
||||||
|
class DriftAnalysisDriver {
|
||||||
|
final DriftBackend backend;
|
||||||
|
final DriftAnalysisCache cache = DriftAnalysisCache();
|
||||||
|
final DriftOptions options;
|
||||||
|
|
||||||
|
DriftAnalysisDriver(this.backend, this.options);
|
||||||
|
|
||||||
|
SqlEngine _newSqlEngine() {
|
||||||
|
return SqlEngine(
|
||||||
|
EngineOptions(
|
||||||
|
useDriftExtensions: true,
|
||||||
|
enabledExtensions: [
|
||||||
|
// todo: Map from options
|
||||||
|
],
|
||||||
|
version: options.sqliteVersion,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Identify all [PendingDriftElement]s in a file.
|
||||||
|
Future<void> _discover(FileState state) async {
|
||||||
|
final extension = state.extension;
|
||||||
|
|
||||||
|
switch (extension) {
|
||||||
|
case '.dart':
|
||||||
|
try {
|
||||||
|
state
|
||||||
|
..parsedDartFile = await backend.readDart(state.uri)
|
||||||
|
..kind = FileKind.dartLibrary;
|
||||||
|
} catch (e, s) {
|
||||||
|
backend.log
|
||||||
|
.fine('Could not read Dart library from ${state.uri}', e, s);
|
||||||
|
state.kind = FileKind.invalid;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '.drift':
|
||||||
|
case '.moor':
|
||||||
|
final engine = _newSqlEngine();
|
||||||
|
String contents;
|
||||||
|
try {
|
||||||
|
contents = await backend.readAsString(state.uri);
|
||||||
|
state.kind = FileKind.driftFile;
|
||||||
|
} catch (e, s) {
|
||||||
|
backend.log.fine('Could not read drift sources ${state.uri}', e, s);
|
||||||
|
state.kind = FileKind.invalid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: Handle parse errors
|
||||||
|
final parsed = engine.parseDriftFile(contents);
|
||||||
|
state.parsedDriftFile = parsed.rootNode as DriftFile;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> fullyAnalyze(Uri uri) async {
|
||||||
|
var known = cache.knownFiles[uri];
|
||||||
|
|
||||||
|
if (known == null || !known.contentsFresh) {
|
||||||
|
await _discover(cache.notifyFileChanged(uri));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
class AnalysisError {}
|
|
@ -19,4 +19,5 @@ class DriftDeclaration {
|
||||||
|
|
||||||
abstract class DriftElement {
|
abstract class DriftElement {
|
||||||
DriftElementId get id;
|
DriftElementId get id;
|
||||||
|
DriftDeclaration get declaration;
|
||||||
}
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
abstract class TemporaryResult {}
|
||||||
|
|
||||||
|
class TemporaryDriftTable extends TemporaryResult {
|
||||||
|
final TableInducingStatement statement;
|
||||||
|
|
||||||
|
TemporaryDriftTable(this.statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TemporaryDriftView extends TemporaryResult {
|
||||||
|
final CreateViewStatement statement;
|
||||||
|
|
||||||
|
TemporaryDriftView(this.statement);
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ homepage: https://drift.simonbinder.eu/
|
||||||
issue_tracker: https://github.com/simolus3/drift/issues
|
issue_tracker: https://github.com/simolus3/drift/issues
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.14.0 <3.0.0'
|
sdk: '>=2.17.0 <3.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
charcode: ^1.2.0
|
charcode: ^1.2.0
|
||||||
|
|
Loading…
Reference in New Issue