mirror of https://github.com/AMT-Cheif/drift.git
Implement basic functionality of the analyzer plugin
This commit is contained in:
parent
10dca6a8a9
commit
1fcc6facee
|
@ -1,4 +1,3 @@
|
|||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:build/build.dart' hide log;
|
||||
|
|
|
@ -88,19 +88,20 @@ class MoorDriver implements AnalysisDriverGeneric {
|
|||
String absolutePath(Uri reference, {Uri base}) {
|
||||
final factory = dartDriver.sourceFactory;
|
||||
final baseSource = base == null ? null : factory.forUri2(base);
|
||||
|
||||
final source =
|
||||
dartDriver.sourceFactory.resolveUri(baseSource, reference.toString());
|
||||
return source.fullName;
|
||||
}
|
||||
|
||||
PluginTask _createTask(String path) {
|
||||
final uri = Uri.parse(path);
|
||||
final uri = Uri.parse(path).replace(scheme: 'file');
|
||||
return PluginTask(uri, this);
|
||||
}
|
||||
|
||||
@override
|
||||
set priorityFiles(List<String> priorityPaths) {
|
||||
_tracker.setPriorityFiles(priorityPaths);
|
||||
_tracker.setPriorityFiles(priorityPaths.where(_ownsFile));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -46,7 +46,7 @@ class FileTracker {
|
|||
_putInQueue(addFile(path));
|
||||
}
|
||||
|
||||
void setPriorityFiles(List<String> priority) {
|
||||
void setPriorityFiles(Iterable<String> priority) {
|
||||
// remove prioritized flag from existing files
|
||||
for (var file in _currentPriority) {
|
||||
_updateFile(file, (f) => f._prioritized = false);
|
||||
|
|
|
@ -13,9 +13,9 @@ void setupLogger(MoorPlugin plugin) {
|
|||
Logger.root.level = Level.ALL;
|
||||
Logger.root.onRecord.listen((LogRecord rec) {
|
||||
if (rec.level >= Level.INFO) {
|
||||
final isFatal = rec.level >= Level.WARNING;
|
||||
final isFatal = rec.level > Level.WARNING;
|
||||
final error =
|
||||
PluginErrorParams(isFatal, rec.message, rec.stackTrace?.toString());
|
||||
PluginErrorParams(isFatal, rec.message, rec.stackTrace.toString());
|
||||
|
||||
plugin.channel.sendNotification(error.toNotification());
|
||||
}
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
import 'package:analyzer/context/context_root.dart';
|
||||
// ignore: implementation_imports
|
||||
import 'package:analyzer/src/context/builder.dart';
|
||||
import 'package:analyzer/src/context/context_root.dart'; // ignore: implementation_imports
|
||||
import 'package:analyzer/src/context/builder.dart'; // ignore: implementation_imports
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer_plugin/plugin/folding_mixin.dart';
|
||||
import 'package:analyzer_plugin/plugin/highlights_mixin.dart';
|
||||
import 'package:analyzer_plugin/plugin/outline_mixin.dart';
|
||||
import 'package:analyzer_plugin/plugin/plugin.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
|
||||
import 'package:analyzer_plugin/utilities/folding/folding.dart';
|
||||
import 'package:analyzer_plugin/utilities/highlights/highlights.dart';
|
||||
import 'package:analyzer_plugin/utilities/outline/outline.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/backend/file_tracker.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/services/folding.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/services/highlights.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/services/outline.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/services/requests.dart';
|
||||
|
||||
import 'backend/driver.dart';
|
||||
import 'backend/logger.dart';
|
||||
|
||||
class MoorPlugin extends ServerPlugin {
|
||||
class MoorPlugin extends ServerPlugin
|
||||
with OutlineMixin, HighlightsMixin, FoldingMixin {
|
||||
MoorPlugin(ResourceProvider provider) : super(provider) {
|
||||
setupLogger(this);
|
||||
}
|
||||
|
@ -61,4 +71,38 @@ class MoorPlugin extends ServerPlugin {
|
|||
if (driver is! MoorDriver) return null;
|
||||
return driver as MoorDriver;
|
||||
}
|
||||
|
||||
Future<MoorRequest> _createMoorRequest(String path) async {
|
||||
final driver = _moorDriverForPath(path);
|
||||
final task = await driver.parseMoorFile(path);
|
||||
|
||||
return MoorRequest(task, resourceProvider);
|
||||
}
|
||||
|
||||
@override
|
||||
List<OutlineContributor> getOutlineContributors(String path) {
|
||||
return const [MoorOutlineContributor()];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<OutlineRequest> getOutlineRequest(String path) =>
|
||||
_createMoorRequest(path);
|
||||
|
||||
@override
|
||||
List<HighlightsContributor> getHighlightsContributors(String path) {
|
||||
return const [MoorHighlightContributor()];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<HighlightsRequest> getHighlightsRequest(String path) =>
|
||||
_createMoorRequest(path);
|
||||
|
||||
@override
|
||||
List<FoldingContributor> getFoldingContributors(String path) {
|
||||
return const [MoorFoldingContributor()];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<FoldingRequest> getFoldingRequest(String path) =>
|
||||
_createMoorRequest(path);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:analyzer_plugin/utilities/folding/folding.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/services/requests.dart';
|
||||
import 'package:sqlparser/sqlparser.dart';
|
||||
|
||||
class MoorFoldingContributor implements FoldingContributor {
|
||||
const MoorFoldingContributor();
|
||||
|
||||
@override
|
||||
void computeFolding(FoldingRequest request, FoldingCollector collector) {
|
||||
final moorRequest = request as MoorRequest;
|
||||
|
||||
final visitor = _FoldingVisitor(collector);
|
||||
for (var stmt in moorRequest.resolvedTask.lastResult.statements) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _FoldingVisitor extends RecursiveVisitor<void> {
|
||||
final FoldingCollector collector;
|
||||
|
||||
_FoldingVisitor(this.collector);
|
||||
|
||||
@override
|
||||
void visitCreateTableStatement(CreateTableStatement e) {
|
||||
final startBody = e.openingBracket;
|
||||
final endBody = e.closingBracket;
|
||||
|
||||
// report everything between the two brackets as class body
|
||||
final first = startBody.span.end.offset + 1;
|
||||
final last = endBody.span.start.offset - 1;
|
||||
|
||||
if (last - first < 0) return; // empty body, e.g. CREATE TABLE ()
|
||||
|
||||
collector.addRegion(first, last - first, FoldingKind.CLASS_BODY);
|
||||
}
|
||||
}
|
|
@ -1,50 +1,29 @@
|
|||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:analyzer_plugin/utilities/highlights/highlights.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/services/highlights/request.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/services/requests.dart';
|
||||
import 'package:sqlparser/sqlparser.dart';
|
||||
|
||||
const _notBuiltIn = {
|
||||
TokenType.numberLiteral,
|
||||
TokenType.stringLiteral,
|
||||
TokenType.identifier,
|
||||
TokenType.leftParen,
|
||||
TokenType.rightParen,
|
||||
TokenType.comma,
|
||||
TokenType.star,
|
||||
TokenType.less,
|
||||
TokenType.lessEqual,
|
||||
TokenType.lessMore,
|
||||
TokenType.equal,
|
||||
TokenType.more,
|
||||
TokenType.moreEqual,
|
||||
TokenType.shiftRight,
|
||||
TokenType.shiftLeft,
|
||||
TokenType.exclamationEqual,
|
||||
TokenType.plus,
|
||||
TokenType.minus,
|
||||
};
|
||||
|
||||
class SqlHighlighter implements HighlightsContributor {
|
||||
const SqlHighlighter();
|
||||
class MoorHighlightContributor implements HighlightsContributor {
|
||||
const MoorHighlightContributor();
|
||||
|
||||
@override
|
||||
void computeHighlights(
|
||||
HighlightsRequest request, HighlightsCollector collector) {
|
||||
if (request is! MoorHighlightingRequest) {
|
||||
if (request is! MoorRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
final typedRequest = request as MoorHighlightingRequest;
|
||||
final typedRequest = request as MoorRequest;
|
||||
final visitor = _HighlightingVisitor(collector);
|
||||
|
||||
final result = typedRequest.task.lastResult;
|
||||
final result = typedRequest.resolvedTask.lastResult;
|
||||
|
||||
for (var stmt in result.statements) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
|
||||
for (var token in result.tokens) {
|
||||
if (!_notBuiltIn.contains(token.type)) {
|
||||
if (token is KeywordToken) {
|
||||
final start = token.span.start.offset;
|
||||
final length = token.span.length;
|
||||
collector.addRegion(start, length, HighlightRegionType.BUILT_IN);
|
|
@ -1,13 +0,0 @@
|
|||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer_plugin/utilities/highlights/highlights.dart';
|
||||
import 'package:moor_generator/src/analyzer/session.dart';
|
||||
|
||||
class MoorHighlightingRequest extends HighlightsRequest {
|
||||
@override
|
||||
final String path;
|
||||
@override
|
||||
final ResourceProvider resourceProvider;
|
||||
final MoorTask task;
|
||||
|
||||
MoorHighlightingRequest(this.task, this.path, this.resourceProvider);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:analyzer_plugin/utilities/outline/outline.dart';
|
||||
import 'package:moor_generator/src/backends/plugin/services/requests.dart';
|
||||
import 'package:sqlparser/sqlparser.dart';
|
||||
|
||||
const _defaultFlags = 0;
|
||||
|
||||
class MoorOutlineContributor implements OutlineContributor {
|
||||
const MoorOutlineContributor();
|
||||
|
||||
@override
|
||||
void computeOutline(OutlineRequest request, OutlineCollector collector) {
|
||||
final moorRequest = request as MoorRequest;
|
||||
final file = moorRequest.path;
|
||||
|
||||
final libraryElement = Element(ElementKind.FILE, file, _defaultFlags);
|
||||
collector.startElement(
|
||||
libraryElement, 0, moorRequest.resolvedTask.content.length);
|
||||
|
||||
final visitor = _OutlineVisitor(collector);
|
||||
for (var stmt in moorRequest.resolvedTask.lastResult.statements) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
|
||||
collector.endElement();
|
||||
}
|
||||
}
|
||||
|
||||
class _OutlineVisitor extends RecursiveVisitor<void> {
|
||||
final OutlineCollector collector;
|
||||
|
||||
_OutlineVisitor(this.collector);
|
||||
|
||||
Element _startElement(ElementKind kind, String name, AstNode e) {
|
||||
final element = Element(kind, name, _defaultFlags);
|
||||
|
||||
final offset = e.firstPosition;
|
||||
final length = e.lastPosition - offset;
|
||||
collector.startElement(element, offset, length);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitCreateTableStatement(CreateTableStatement e) {
|
||||
_startElement(ElementKind.CLASS, e.tableName, e);
|
||||
super.visitChildren(e);
|
||||
collector.endElement();
|
||||
}
|
||||
|
||||
@override
|
||||
void visitColumnDefinition(ColumnDefinition e) {
|
||||
_startElement(ElementKind.FIELD, e.columnName, e);
|
||||
super.visitChildren(e);
|
||||
collector.endElement();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer_plugin/utilities/folding/folding.dart';
|
||||
import 'package:analyzer_plugin/utilities/highlights/highlights.dart';
|
||||
import 'package:analyzer_plugin/utilities/outline/outline.dart';
|
||||
import 'package:moor_generator/src/analyzer/session.dart';
|
||||
|
||||
class MoorRequest implements OutlineRequest, HighlightsRequest, FoldingRequest {
|
||||
final MoorTask resolvedTask;
|
||||
@override
|
||||
final ResourceProvider resourceProvider;
|
||||
|
||||
MoorRequest(this.resolvedTask, this.resourceProvider);
|
||||
|
||||
@override
|
||||
String get path => resolvedTask.backendTask.entrypoint.toFilePath();
|
||||
}
|
|
@ -8,7 +8,7 @@ class ImportStatement extends Statement {
|
|||
ImportStatement(this.importedFile);
|
||||
|
||||
@override
|
||||
T accept<T>(AstVisitor<T> visitor) {}
|
||||
T accept<T>(AstVisitor<T> visitor) => visitor.visitMoorImportStatement(this);
|
||||
|
||||
@override
|
||||
final Iterable<AstNode> childNodes = const [];
|
||||
|
|
|
@ -9,6 +9,9 @@ class CreateTableStatement extends Statement with SchemaStatement {
|
|||
final List<TableConstraint> tableConstraints;
|
||||
final bool withoutRowId;
|
||||
|
||||
Token openingBracket;
|
||||
Token closingBracket;
|
||||
|
||||
CreateTableStatement(
|
||||
{this.ifNotExists = false,
|
||||
@required this.tableName,
|
||||
|
|
|
@ -19,7 +19,7 @@ mixin SchemaParser on ParserBase {
|
|||
_consumeIdentifier('Expected a table name', lenient: true);
|
||||
|
||||
// we don't currently support CREATE TABLE x AS SELECT ... statements
|
||||
_consume(
|
||||
final leftParen = _consume(
|
||||
TokenType.leftParen, 'Expected opening parenthesis to list columns');
|
||||
|
||||
final columns = <ColumnDefinition>[];
|
||||
|
@ -42,7 +42,8 @@ mixin SchemaParser on ParserBase {
|
|||
}
|
||||
} while (_matchOne(TokenType.comma));
|
||||
|
||||
_consume(TokenType.rightParen, 'Expected closing parenthesis');
|
||||
final rightParen =
|
||||
_consume(TokenType.rightParen, 'Expected closing parenthesis');
|
||||
|
||||
var withoutRowId = false;
|
||||
if (_matchOne(TokenType.without)) {
|
||||
|
@ -57,7 +58,10 @@ mixin SchemaParser on ParserBase {
|
|||
withoutRowId: withoutRowId,
|
||||
columns: columns,
|
||||
tableConstraints: tableConstraints,
|
||||
)..setSpan(first, _previous);
|
||||
)
|
||||
..setSpan(first, _previous)
|
||||
..openingBracket = leftParen
|
||||
..closingBracket = rightParen;
|
||||
}
|
||||
|
||||
ColumnDefinition _columnDefinition() {
|
||||
|
|
Loading…
Reference in New Issue