mirror of https://github.com/AMT-Cheif/drift.git
Support virtual tables in the analyzer plugin
This commit is contained in:
parent
643ef5640c
commit
6434f7a7d5
|
@ -0,0 +1,8 @@
|
|||
targets:
|
||||
$default:
|
||||
builders:
|
||||
moor_generator:
|
||||
options:
|
||||
sqlite_modules:
|
||||
- json1
|
||||
- fts5
|
|
@ -7,6 +7,8 @@ CREATE TABLE playground (
|
|||
name VARCHAR NOT NULL
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE email USING fts5(name);
|
||||
|
||||
unknownColumn: SELECT * FROM playground WHERE bar = 'foo';
|
||||
syntaxError: SELECT 3 + FROM playground;
|
||||
lints: INSERT INTO playground DEFAULT VALUES;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:moor_generator/moor_generator.dart';
|
||||
import 'package:moor_generator/src/analyzer/errors.dart';
|
||||
import 'package:moor_generator/src/analyzer/runner/steps.dart';
|
||||
import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart';
|
||||
import 'package:moor_generator/src/model/declarations/declaration.dart';
|
||||
|
@ -16,7 +17,15 @@ class CreateTableReader {
|
|||
CreateTableReader(this.stmt, this.step);
|
||||
|
||||
MoorTable extractTable(TypeMapper mapper) {
|
||||
final table = SchemaFromCreateTable(moorExtensions: true).read(stmt);
|
||||
Table table;
|
||||
try {
|
||||
table = SchemaFromCreateTable(moorExtensions: true).read(stmt);
|
||||
} catch (e) {
|
||||
step.reportError(ErrorInMoorFile(
|
||||
span: stmt.tableNameToken.span,
|
||||
message: 'Could not extract schema information for this table: $e',
|
||||
));
|
||||
}
|
||||
|
||||
final foundColumns = <String, MoorColumn>{};
|
||||
final primaryKey = <MoorColumn>{};
|
||||
|
|
|
@ -17,7 +17,7 @@ const _fileEndings = {
|
|||
class MoorSession {
|
||||
final FileGraph fileGraph = FileGraph();
|
||||
final Backend backend;
|
||||
final MoorOptions options;
|
||||
MoorOptions options;
|
||||
|
||||
final _completedTasks = StreamController<Task>.broadcast();
|
||||
final _changedFiles = StreamController<List<FoundFile>>.broadcast();
|
||||
|
|
|
@ -66,7 +66,7 @@ abstract class BaseMoorPlugin extends ServerPlugin {
|
|||
|
||||
final tracker = FileTracker();
|
||||
final driver = MoorDriver(tracker, analysisDriverScheduler, dartDriver,
|
||||
fileContentOverlay, resourceProvider, options);
|
||||
fileContentOverlay, resourceProvider, options, contextRoot.root);
|
||||
didCreateDriver(driver);
|
||||
|
||||
return driver;
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:moor_generator/src/analyzer/options.dart';
|
|||
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
|
||||
import 'package:moor_generator/src/analyzer/session.dart';
|
||||
import 'package:moor_generator/src/services/ide/moor_ide.dart';
|
||||
import 'package:moor_generator/src/utils/options_reader.dart' as options;
|
||||
|
||||
import 'backend.dart';
|
||||
import 'file_tracker.dart';
|
||||
|
@ -26,6 +27,7 @@ class MoorDriver implements AnalysisDriverGeneric {
|
|||
/// unsaved files.
|
||||
final FileContentOverlay contentOverlay;
|
||||
final ResourceProvider _resourceProvider;
|
||||
final String contextRoot;
|
||||
|
||||
/* late final */ MoorSession session;
|
||||
StreamSubscription _fileChangeSubscription;
|
||||
|
@ -33,7 +35,7 @@ class MoorDriver implements AnalysisDriverGeneric {
|
|||
|
||||
MoorDriver(this._tracker, this._scheduler, this.dartDriver,
|
||||
this.contentOverlay, this._resourceProvider,
|
||||
[MoorOptions options]) {
|
||||
[MoorOptions options, this.contextRoot]) {
|
||||
_scheduler.add(this);
|
||||
final backend = CommonBackend(this);
|
||||
|
||||
|
@ -110,6 +112,20 @@ class MoorDriver implements AnalysisDriverGeneric {
|
|||
}
|
||||
}
|
||||
|
||||
/// Attempt to load the appropriate [MoorOptions] by reading the `build.yaml`
|
||||
/// located in the context root.
|
||||
///
|
||||
/// When something fails, the default options will be used an an error message
|
||||
/// will be logged.
|
||||
Future<void> tryToLoadOptions() async {
|
||||
try {
|
||||
final result = await options.fromRootDir(contextRoot);
|
||||
session.options = result;
|
||||
} catch (e, s) {
|
||||
Logger.root.info('Could not load options, using defaults', e, s);
|
||||
}
|
||||
}
|
||||
|
||||
String readFile(String path) {
|
||||
final overlay = contentOverlay[path];
|
||||
if (overlay != null) {
|
||||
|
|
|
@ -45,6 +45,7 @@ class MoorPlugin extends BaseMoorPlugin
|
|||
|
||||
@override
|
||||
void didCreateDriver(MoorDriver driver) {
|
||||
driver.tryToLoadOptions();
|
||||
driver.session
|
||||
.completedFiles()
|
||||
.where((file) => file.isParsed)
|
||||
|
|
|
@ -46,6 +46,25 @@ class _OutlineVisitor extends RecursiveVisitor<void, void> {
|
|||
collector.endElement();
|
||||
}
|
||||
|
||||
@override
|
||||
void visitCreateVirtualTableStatement(
|
||||
CreateVirtualTableStatement e, void arg) {
|
||||
_startElement(ElementKind.CLASS, e.tableName, e);
|
||||
|
||||
// if the file is analyzed, we can report analyzed columns
|
||||
final resolved = request.parsedMoor.declaredTables
|
||||
?.singleWhere((t) => t.sqlName == e.tableName, orElse: () => null);
|
||||
|
||||
if (resolved != null) {
|
||||
for (final column in resolved.columns) {
|
||||
_startElement(ElementKind.FIELD, column.name.name, e);
|
||||
collector.endElement();
|
||||
}
|
||||
}
|
||||
|
||||
collector.endElement();
|
||||
}
|
||||
|
||||
@override
|
||||
void visitColumnDefinition(ColumnDefinition e, void arg) {
|
||||
// we use parameters instead of returnType because VS Code doesn't show
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:build_config/build_config.dart';
|
||||
import 'package:moor_generator/src/analyzer/options.dart';
|
||||
import 'package:moor_generator/src/utils/options_reader.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:stream_transform/stream_transform.dart';
|
||||
|
||||
|
@ -15,7 +16,7 @@ class MoorProject {
|
|||
final Directory directory;
|
||||
|
||||
MoorProject(this.buildConfig, this.directory)
|
||||
: moorOptions = _readOptions(buildConfig);
|
||||
: moorOptions = readOptionsFromConfig(buildConfig);
|
||||
|
||||
Stream<File> get sourceFiles {
|
||||
const topLevelDirs = {'lib', 'test', 'bin', 'example'};
|
||||
|
@ -33,16 +34,6 @@ class MoorProject {
|
|||
}).whereType();
|
||||
}
|
||||
|
||||
static MoorOptions _readOptions(BuildConfig config) {
|
||||
final options = config.buildTargets.values
|
||||
.map((t) => t.builders['moor_generator:moor_generator']?.options)
|
||||
.where((t) => t != null)
|
||||
.map((json) => MoorOptions.fromJson(json));
|
||||
|
||||
final iterator = options.iterator;
|
||||
return iterator.moveNext() ? iterator.current : const MoorOptions();
|
||||
}
|
||||
|
||||
static Future<MoorProject> readFromDir(Directory directory) async {
|
||||
final config = await BuildConfig.fromPackageDir(directory.path);
|
||||
|
||||
|
|
|
@ -89,6 +89,11 @@ class _HighlightingVisitor extends RecursiveVisitor<void, void> {
|
|||
_contribute(e.tableNameToken, HighlightRegionType.CLASS);
|
||||
}
|
||||
|
||||
if (e is CreateVirtualTableStatement && e.moduleNameToken != null) {
|
||||
_contribute(
|
||||
e.moduleNameToken, HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE);
|
||||
}
|
||||
|
||||
visitChildren(e, arg);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import 'package:build_config/build_config.dart';
|
||||
import 'package:moor_generator/src/analyzer/options.dart';
|
||||
|
||||
Future<MoorOptions> fromRootDir(String path) async {
|
||||
final options = await BuildConfig.fromPackageDir(path);
|
||||
return readOptionsFromConfig(options);
|
||||
}
|
||||
|
||||
MoorOptions readOptionsFromConfig(BuildConfig config) {
|
||||
final options = config.buildTargets.values
|
||||
.map((t) => t.builders['moor_generator:moor_generator']?.options)
|
||||
.where((t) => t != null)
|
||||
.map((json) => MoorOptions.fromJson(json));
|
||||
|
||||
final iterator = options.iterator;
|
||||
return iterator.moveNext() ? iterator.current : const MoorOptions();
|
||||
}
|
|
@ -58,6 +58,7 @@ class CreateTableStatement extends TableInducingStatement {
|
|||
class CreateVirtualTableStatement extends TableInducingStatement {
|
||||
/// The module that will be invoked when creating the virtual table.
|
||||
final String moduleName;
|
||||
Token moduleNameToken;
|
||||
|
||||
/// Arguments passed to the module. Since the specific module is responsible
|
||||
/// for parsing them, the general parser only exposes them as strings with a
|
||||
|
|
|
@ -149,7 +149,8 @@ mixin SchemaParser on ParserBase {
|
|||
overriddenDataClassName: moorDataClassName,
|
||||
)
|
||||
..setSpan(first, _previous)
|
||||
..tableNameToken = nameToken;
|
||||
..tableNameToken = nameToken
|
||||
..moduleNameToken = moduleName;
|
||||
}
|
||||
|
||||
String _overriddenDataClassName() {
|
||||
|
|
Loading…
Reference in New Issue