Improve some docs, abstract base plugin class

This commit is contained in:
Simon Binder 2019-12-17 12:05:09 +01:00
parent d2864d6859
commit a8aa65e4c1
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
8 changed files with 117 additions and 71 deletions

View File

@ -37,7 +37,7 @@ blog = "/:section/:year/:month/:day/:slug/"
## Configuration for BlackFriday markdown parser: https://github.com/russross/blackfriday
[blackfriday]
plainIDAnchors = true
hrefTargetBlank = true
hrefTargetBlank = false
angledQuotes = false
latexDashes = true

View File

@ -61,7 +61,7 @@ At the moment, moor supports these options:
__Note__: This enables extensions in the analyzer for custom queries only. For instance, when the `json1` extension is
enabled, the [`json`](https://www.sqlite.org/json1.html) functions can be used in moor files. This doesn't necessarily
mean that those functions are supported at runtime! Both extensions are available on iOS 11 or later. On Android, they're
only available when using `moor_ffi`.
only available when using `moor_ffi`. See [our docs]({{< relref "extensions.md" >}}) for more details on them.
```yaml
targets:

View File

@ -54,7 +54,7 @@ return query.watch().map((rows) {
_Note_: `readTable` returns `null` when an entity is not present in the row. For instance, todo entries
might not be in any category.For a row without a category, `row.readTable(categories)` would return `null`.
## Custom expressions
## Custom columns
Select statements aren't limited to columns from tables. You can also include more complex expressions in the
query. For each row in the result, those expressions will be evaluated by the database engine.

View File

@ -4,13 +4,13 @@ weight: 10
description: Information on json1 and fts5 support in the generator
---
_Note_: Since `moor_flutter` uses the sqlite version shipped on the device, the extensions might not
_Note_: Since `moor_flutter` uses the sqlite version shipped on the device, these extensions might not
be available on all devices. When using these extensions, using `moor_ffi` is strongly recommended.
This enables the extensions on all Android devices and on iOS 11 and later.
This enables the extensions listed here on all Android devices and on iOS 11 and later.
## json1
To enable the json1 extension in moor files and compiled queries, modify the
To enable the json1 extension in moor files and compiled queries, modify your
[build options]({{<relref "../Advanced Features/builder_options.md">}}) to include
`json1` in the `sqlite_module` section.

View File

@ -0,0 +1,96 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/builder.dart'; // ignore: implementation_imports
import 'package:analyzer/src/context/context_root.dart'; // ignore: implementation_imports
// ignore: implementation_imports
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriverScheduler;
import 'package:analyzer_plugin/plugin/plugin.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as proto;
import 'package:meta/meta.dart';
import 'package:moor_generator/src/analyzer/options.dart';
import 'driver.dart';
import 'file_tracker.dart';
abstract class BaseMoorPlugin extends ServerPlugin {
BaseMoorPlugin(ResourceProvider provider) : super(provider);
/// The [AnalysisDriverScheduler] used to analyze Dart files.
///
/// We don't use a the single [analysisDriverScheduler] from the plugin
/// because it causes deadlocks when the [MoorDriver] wants to analyze Dart
/// files.
AnalysisDriverScheduler get dartScheduler {
if (_dartScheduler == null) {
_dartScheduler = AnalysisDriverScheduler(performanceLog);
_dartScheduler.start();
}
return _dartScheduler;
}
AnalysisDriverScheduler _dartScheduler;
@override
List<String> get fileGlobsToAnalyze => const ['*.moor'];
@override
String get name => 'Moor plugin';
@override
// docs say that this should a version of _this_ plugin, but they lie. this
// version will be used to determine compatibility with the analyzer
String get version => '2.0.0-alpha.0';
@override
String get contactInfo =>
'Create an issue at https://github.com/simolus3/moor/';
@override
MoorDriver createAnalysisDriver(proto.ContextRoot contextRoot,
{MoorOptions options}) {
// create an analysis driver we can use to resolve Dart files
final analyzerRoot = ContextRoot(
contextRoot.root,
contextRoot.exclude,
pathContext: resourceProvider.pathContext,
)..optionsFilePath = contextRoot.optionsFile;
final builder = ContextBuilder(resourceProvider, sdkManager, null)
..analysisDriverScheduler = dartScheduler
..byteStore = byteStore
..performanceLog = performanceLog
..fileContentOverlay = fileContentOverlay;
// todo we listen because we copied this from the angular plugin. figure out
// why exactly this is necessary
final dartDriver = builder.buildDriver(analyzerRoot)
..results.listen((_) {}) // Consume the stream, otherwise we leak.
..exceptions.listen((_) {}); // Consume the stream, otherwise we leak.
final tracker = FileTracker();
final driver = MoorDriver(tracker, analysisDriverScheduler, dartDriver,
fileContentOverlay, resourceProvider, options);
didCreateDriver(driver);
return driver;
}
@visibleForOverriding
void didCreateDriver(MoorDriver driver) {}
@override
MoorDriver driverForPath(String path) {
final driver = super.driverForPath(path);
if (driver is MoorDriver) {
return driver;
}
return null;
}
@override
Future<proto.PluginShutdownResult> handlePluginShutdown(
proto.PluginShutdownParams parameters) async {
for (final driver in driverMap.values) {
driver.dispose();
}
return proto.PluginShutdownResult();
}
}

View File

@ -1,17 +1,11 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/context/builder.dart'; // ignore: implementation_imports
import 'package:analyzer/src/context/context_root.dart'; // ignore: implementation_imports
// ignore: implementation_imports
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriverScheduler;
import 'package:analyzer_plugin/plugin/assist_mixin.dart';
import 'package:analyzer_plugin/plugin/completion_mixin.dart';
import 'package:analyzer_plugin/plugin/folding_mixin.dart';
import 'package:analyzer_plugin/plugin/highlights_mixin.dart';
import 'package:analyzer_plugin/plugin/navigation_mixin.dart';
import 'package:analyzer_plugin/plugin/outline_mixin.dart';
import 'package:analyzer_plugin/plugin/plugin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_plugin/utilities/assist/assist.dart';
@ -20,10 +14,9 @@ import 'package:analyzer_plugin/utilities/folding/folding.dart';
import 'package:analyzer_plugin/utilities/highlights/highlights.dart';
import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
import 'package:analyzer_plugin/utilities/outline/outline.dart';
import 'package:moor_generator/src/analyzer/options.dart';
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
import 'package:moor_generator/src/backends/common/base_plugin.dart';
import 'package:moor_generator/src/backends/common/driver.dart';
import 'package:moor_generator/src/backends/common/file_tracker.dart';
import 'package:moor_generator/src/backends/plugin/services/assists/assist_service.dart';
import 'package:moor_generator/src/backends/plugin/services/autocomplete.dart';
import 'package:moor_generator/src/backends/plugin/services/errors.dart';
@ -35,7 +28,7 @@ import 'package:moor_generator/src/backends/plugin/services/requests.dart';
import 'logger.dart';
class MoorPlugin extends ServerPlugin
class MoorPlugin extends BaseMoorPlugin
with
OutlineMixin,
HighlightsMixin,
@ -44,77 +37,31 @@ class MoorPlugin extends ServerPlugin
AssistsMixin,
NavigationMixin {
MoorPlugin(ResourceProvider provider) : super(provider) {
dartScheduler = AnalysisDriverScheduler(performanceLog);
setupLogger(this);
dartScheduler.start();
errorService = ErrorService(this);
}
factory MoorPlugin.forProduction() {
return MoorPlugin(PhysicalResourceProvider.INSTANCE);
}
@override
final List<String> fileGlobsToAnalyze = const ['*.moor'];
@override
final String name = 'Moor plugin';
@override
// docs say that this should a version of _this_ plugin, but they lie. this
// version will be used to determine compatibility with the analyzer
final String version = '2.0.0-alpha.0';
@override
final String contactInfo =
'Create an issue at https://github.com/simolus3/moor/';
AnalysisDriverScheduler dartScheduler;
ErrorService errorService;
@override
MoorDriver createAnalysisDriver(plugin.ContextRoot contextRoot,
{MoorOptions options}) {
// create an analysis driver we can use to resolve Dart files
final analyzerRoot = ContextRoot(contextRoot.root, contextRoot.exclude,
pathContext: resourceProvider.pathContext)
..optionsFilePath = contextRoot.optionsFile;
final builder = ContextBuilder(resourceProvider, sdkManager, null)
..analysisDriverScheduler = dartScheduler
..byteStore = byteStore
..performanceLog = performanceLog
..fileContentOverlay = fileContentOverlay;
// todo we listen because we copied this from the angular plugin. figure out
// why exactly this is necessary
final dartDriver = builder.buildDriver(analyzerRoot)
..results.listen((_) {}) // Consume the stream, otherwise we leak.
..exceptions.listen((_) {}); // Consume the stream, otherwise we leak.
final tracker = FileTracker();
final errorService = ErrorService(this);
final driver = MoorDriver(tracker, analysisDriverScheduler, dartDriver,
fileContentOverlay, resourceProvider, options);
void didCreateDriver(MoorDriver driver) {
driver.completedFiles().where((file) => file.isParsed).listen((file) {
sendNotificationsForFile(file.uri.path);
errorService.handleResult(file);
});
return driver;
}
@override
void contentChanged(String path) {
_moorDriverForPath(path)?.handleFileChanged(path);
}
MoorDriver _moorDriverForPath(String path) {
final driver = super.driverForPath(path);
if (driver is! MoorDriver) return null;
return driver as MoorDriver;
driverForPath(path)?.handleFileChanged(path);
}
Future<FoundFile> _waitParsed(String path) async {
final driver = _moorDriverForPath(path);
final driver = driverForPath(path);
if (driver == null) {
throw RequestFailure(plugin.RequestError(
plugin.RequestErrorCode.INVALID_PARAMETER,

View File

@ -36,7 +36,7 @@ class ErrorService {
}
final params = AnalysisErrorsParams(path, errors);
plugin.channel?.sendNotification(params.toNotification());
plugin.channel.sendNotification(params.toNotification());
}
Location _findLocationForError(MoorError error, String path) {

View File

@ -5,21 +5,20 @@ import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:cli_util/cli_util.dart';
import 'package:moor_generator/src/analyzer/options.dart';
import 'package:moor_generator/src/backends/common/base_plugin.dart';
import 'package:moor_generator/src/backends/common/driver.dart';
import 'package:path/path.dart' as p;
import 'package:moor_generator/src/backends/plugin/plugin.dart';
class StandaloneMoorAnalyzer {
// the analyzer plugin package is wrapping a lot of unstable analyzer apis
// for us. It's also managed by the Dart team, so creating a fake plugin to
// create Dart analysis drivers seems like the most stable approach.
final MoorPlugin _fakePlugin;
final BaseMoorPlugin _fakePlugin;
ResourceProvider get resources => _fakePlugin.resourceProvider;
StandaloneMoorAnalyzer(ResourceProvider provider)
: _fakePlugin = MoorPlugin(provider);
: _fakePlugin = _FakePlugin(provider);
factory StandaloneMoorAnalyzer.inMemory() {
return StandaloneMoorAnalyzer(MemoryResourceProvider());
@ -49,3 +48,7 @@ class StandaloneMoorAnalyzer {
);
}
}
class _FakePlugin extends BaseMoorPlugin {
_FakePlugin(ResourceProvider provider) : super(provider);
}