Don't use the MoorGenerator as a god class

This commit is contained in:
Simon Binder 2019-06-29 15:34:27 +02:00
parent 53d57d6a96
commit 7becfdcb85
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
8 changed files with 52 additions and 58 deletions

View File

@ -11,5 +11,5 @@ Builder moorBuilder(BuilderOptions options) {
final parsedOptions = MoorOptions(writeFromString);
final state = SharedState(parsedOptions);
return SharedPartBuilder([MoorGenerator(state), DaoGenerator()], 'moor');
return SharedPartBuilder([MoorGenerator(state), DaoGenerator(state)], 'moor');
}

View File

@ -1,11 +1,16 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:moor_generator/src/shared_state.dart';
import 'package:recase/recase.dart';
import 'package:moor/moor.dart';
import 'package:moor_generator/src/model/specified_table.dart';
import 'package:source_gen/source_gen.dart';
class DaoGenerator extends GeneratorForAnnotation<UseDao> {
final SharedState state;
DaoGenerator(this.state);
@override
generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep buildStep) {

View File

@ -1,14 +1,10 @@
import 'package:moor/moor.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/results.dart'; // ignore: implementation_imports
import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:moor_generator/src/errors.dart';
import 'package:moor_generator/src/model/specified_database.dart';
import 'package:moor_generator/src/model/specified_table.dart';
import 'package:moor_generator/src/options.dart';
import 'package:moor_generator/src/parser/column_parser.dart';
import 'package:moor_generator/src/parser/table_parser.dart';
import 'package:moor_generator/src/shared_state.dart';
import 'package:moor_generator/src/writer/database_writer.dart';
import 'package:source_gen/source_gen.dart';
@ -22,16 +18,6 @@ class MoorGenerator extends GeneratorForAnnotation<UseMoor> {
MoorGenerator(this.state);
ElementDeclarationResult loadElementDeclaration(Element element) {
/*final result = _astForLibs.putIfAbsent(element.library.name, () {
// ignore: deprecated_member_use
return ParsedLibraryResultImpl.tmp(element.library);
});*/
// ignore: deprecated_member_use
final result = ParsedLibraryResultImpl.tmp(element.library);
return result.getElementDeclaration(element);
}
@override
generateForAnnotatedElement(
Element element, ConstantReader annotation, BuildStep buildStep) {
@ -44,9 +30,6 @@ class MoorGenerator extends GeneratorForAnnotation<UseMoor> {
.toList();
final queries = annotation.peek('queries')?.listValue ?? [];
state.tableParser ??= TableParser(this);
state.columnParser ??= ColumnParser(this);
final tablesForThisDb = <SpecifiedTable>[];
var resolvedQueries = <SqlQuery>[];

View File

@ -3,7 +3,7 @@ import 'package:analyzer/dart/element/element.dart';
import 'package:moor_generator/src/errors.dart';
import 'package:moor_generator/src/model/specified_column.dart';
import 'package:moor_generator/src/parser/parser.dart';
import 'package:moor_generator/src/moor_generator.dart';
import 'package:moor_generator/src/shared_state.dart';
import 'package:moor_generator/src/utils/type_utils.dart';
import 'package:recase/recase.dart';
@ -37,7 +37,7 @@ const String _errorMessage = 'This getter does not create a valid column that '
'columns are formed. If you have any questions, feel free to raise an issue.';
class ColumnParser extends ParserBase {
ColumnParser(MoorGenerator generator) : super(generator);
ColumnParser(SharedState state) : super(state);
SpecifiedColumn parse(MethodDeclaration getter, Element getterElement) {
/*
@ -52,7 +52,7 @@ class ColumnParser extends ParserBase {
final expr = returnExpressionOfMethod(getter);
if (!(expr is FunctionExpressionInvocation)) {
generator.state.errors.add(MoorError(
state.errors.add(MoorError(
affectedElement: getter.declaredElement,
message: _errorMessage,
critical: true,
@ -84,7 +84,7 @@ class ColumnParser extends ParserBase {
switch (methodName) {
case _methodNamed:
if (foundExplicitName != null) {
generator.state.errors.add(
state.errors.add(
MoorError(
critical: false,
affectedElement: getter.declaredElement,
@ -97,7 +97,7 @@ class ColumnParser extends ParserBase {
foundExplicitName =
readStringLiteral(remainingExpr.argumentList.arguments.first, () {
generator.state.errors.add(
state.errors.add(
MoorError(
critical: false,
affectedElement: getter.declaredElement,
@ -133,7 +133,7 @@ class ColumnParser extends ParserBase {
case _methodCustomConstraint:
foundCustomConstraint =
readStringLiteral(remainingExpr.argumentList.arguments.first, () {
generator.state.errors.add(
state.errors.add(
MoorError(
critical: false,
affectedElement: getter.declaredElement,

View File

@ -1,7 +1,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:moor_generator/src/errors.dart';
import 'package:moor_generator/src/model/specified_table.dart';
import 'package:moor_generator/src/moor_generator.dart';
import 'package:moor_generator/src/shared_state.dart';
class Parser {
List<SpecifiedTable> specifiedTables;
@ -10,15 +10,15 @@ class Parser {
}
class ParserBase {
final MoorGenerator generator;
final SharedState state;
ParserBase(this.generator);
ParserBase(this.state);
Expression returnExpressionOfMethod(MethodDeclaration method) {
final body = method.body;
if (!(body is ExpressionFunctionBody)) {
generator.state.errors.add(MoorError(
state.errors.add(MoorError(
affectedElement: method.declaredElement,
critical: true,
message:

View File

@ -4,14 +4,14 @@ import 'package:moor_generator/src/errors.dart';
import 'package:moor_generator/src/model/specified_column.dart';
import 'package:moor_generator/src/model/specified_table.dart';
import 'package:moor_generator/src/parser/parser.dart';
import 'package:moor_generator/src/shared_state.dart';
import 'package:moor_generator/src/utils/names.dart';
import 'package:moor_generator/src/utils/type_utils.dart';
import 'package:moor_generator/src/moor_generator.dart'; // ignore: implementation_imports
import 'package:recase/recase.dart';
import 'package:moor/sqlite_keywords.dart';
class TableParser extends ParserBase {
TableParser(MoorGenerator generator) : super(generator);
TableParser(SharedState state) : super(state);
SpecifiedTable parse(ClassElement element) {
final sqlName = _parseTableName(element);
@ -52,13 +52,12 @@ class TableParser extends ParserBase {
// we expect something like get tableName => "myTableName", the getter
// must do nothing more complicated
final tableNameDeclaration =
generator.loadElementDeclaration(tableNameGetter);
final tableNameDeclaration = state.loadElementDeclaration(tableNameGetter);
final returnExpr = returnExpressionOfMethod(
tableNameDeclaration.node as MethodDeclaration);
final tableName = readStringLiteral(returnExpr, () {
generator.state.errors.add(MoorError(
state.errors.add(MoorError(
critical: true,
message:
'This getter must return a string literal, and do nothing more',
@ -75,11 +74,11 @@ class TableParser extends ParserBase {
return null;
}
final ast = generator.loadElementDeclaration(primaryKeyGetter).node
final ast = state.loadElementDeclaration(primaryKeyGetter).node
as MethodDeclaration;
final body = ast.body;
if (body is! ExpressionFunctionBody) {
generator.state.errors.add(MoorError(
state.errors.add(MoorError(
affectedElement: primaryKeyGetter,
message: 'This must return a set literal using the => syntax!'));
return null;
@ -103,7 +102,7 @@ class TableParser extends ParserBase {
}
}
} else {
generator.state.errors.add(MoorError(
state.errors.add(MoorError(
affectedElement: primaryKeyGetter,
message: 'This must return a set literal!'));
}
@ -115,10 +114,10 @@ class TableParser extends ParserBase {
return element.fields
.where((field) => isColumn(field.type) && field.getter != null)
.map((field) {
final node = generator.loadElementDeclaration(field.getter).node
as MethodDeclaration;
final node =
state.loadElementDeclaration(field.getter).node as MethodDeclaration;
return generator.state.columnParser.parse(node, field.getter);
return state.columnParser.parse(node, field.getter);
}).toList();
}
}

View File

@ -1,4 +1,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/results.dart'; // ignore: implementation_imports
import 'package:moor/moor.dart' show Table;
import 'package:moor_generator/src/parser/column_parser.dart';
import 'package:moor_generator/src/parser/table_parser.dart';
@ -21,5 +24,14 @@ class SharedState {
final Map<DartType, SpecifiedTable> foundTables = {};
SharedState(this.options);
SharedState(this.options) {
tableParser = TableParser(this);
columnParser = ColumnParser(this);
}
ElementDeclarationResult loadElementDeclaration(Element element) {
// ignore: deprecated_member_use
final result = ParsedLibraryResultImpl.tmp(element.library);
return result.getElementDeclaration(element);
}
}

View File

@ -3,14 +3,12 @@ import 'package:moor_generator/src/model/specified_column.dart';
import 'package:moor_generator/src/options.dart';
import 'package:moor_generator/src/parser/column_parser.dart';
import 'package:moor_generator/src/parser/table_parser.dart';
import 'package:moor_generator/src/moor_generator.dart';
import 'package:moor_generator/src/shared_state.dart';
import 'package:test_api/test_api.dart';
import 'package:build_test/build_test.dart';
void main() async {
LibraryElement testLib;
MoorGenerator generator;
SharedState state;
setUpAll(() async {
@ -53,29 +51,27 @@ void main() async {
});
setUp(() {
state = SharedState(const MoorOptions.defaults());
generator = MoorGenerator(state);
state
..columnParser = ColumnParser(generator)
..tableParser = TableParser(generator);
state = SharedState(const MoorOptions.defaults())
..columnParser = ColumnParser(state)
..tableParser = TableParser(state);
});
group('SQL table name', () {
test('should parse correctly when valid', () {
expect(
TableParser(generator)
TableParser(state)
.parse(testLib.getType('TableWithCustomName'))
.sqlName,
equals('my-fancy-table'));
});
test('should use class name if table name is not specified', () {
expect(TableParser(generator).parse(testLib.getType('Users')).sqlName,
expect(TableParser(state).parse(testLib.getType('Users')).sqlName,
equals('users'));
});
test('should not parse for complex methods', () async {
TableParser(generator).parse(testLib.getType('WrongName'));
TableParser(state).parse(testLib.getType('WrongName'));
expect(state.errors.errors, isNotEmpty);
});
@ -83,7 +79,7 @@ void main() async {
group('Columns', () {
test('should use field name if no name has been set explicitely', () {
final table = TableParser(generator).parse(testLib.getType('Users'));
final table = TableParser(state).parse(testLib.getType('Users'));
final idColumn =
table.columns.singleWhere((col) => col.name.name == 'id');
@ -91,7 +87,7 @@ void main() async {
});
test('should use explicit name, if it exists', () {
final table = TableParser(generator).parse(testLib.getType('Users'));
final table = TableParser(state).parse(testLib.getType('Users'));
final idColumn =
table.columns.singleWhere((col) => col.name.name == 'user_name');
@ -99,7 +95,7 @@ void main() async {
});
test('should parse min and max length for text columns', () {
final table = TableParser(generator).parse(testLib.getType('Users'));
final table = TableParser(state).parse(testLib.getType('Users'));
final idColumn =
table.columns.singleWhere((col) => col.name.name == 'user_name');
@ -108,7 +104,7 @@ void main() async {
});
test('should only parse max length when relevant', () {
final table = TableParser(generator).parse(testLib.getType('Users'));
final table = TableParser(state).parse(testLib.getType('Users'));
final idColumn =
table.columns.singleWhere((col) => col.dartGetterName == 'onlyMax');
@ -118,7 +114,7 @@ void main() async {
test('parses custom constraints', () {
final table =
TableParser(generator).parse(testLib.getType('CustomPrimaryKey'));
TableParser(state).parse(testLib.getType('CustomPrimaryKey'));
final partA =
table.columns.singleWhere((c) => c.dartGetterName == 'partA');
@ -130,7 +126,7 @@ void main() async {
});
test('parsed default values', () {
final table = TableParser(generator).parse(testLib.getType('Users'));
final table = TableParser(state).parse(testLib.getType('Users'));
final defaultsColumn =
table.columns.singleWhere((c) => c.name.name == 'defaults');
@ -139,8 +135,7 @@ void main() async {
});
test('parses custom primary keys', () {
final table =
TableParser(generator).parse(testLib.getType('CustomPrimaryKey'));
final table = TableParser(state).parse(testLib.getType('CustomPrimaryKey'));
expect(table.primaryKey, containsAll(table.columns));
expect(table.columns.any((column) => column.hasAI), isFalse);